Index: utils/emuriver/configure =================================================================== --- utils/emuriver/configure (revision 0) +++ utils/emuriver/configure (revision 0) @@ -0,0 +1,4603 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.59. +# +# Copyright (C) 2003 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 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+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi +DUALCASE=1; export DUALCASE # for MKS sh + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; 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 + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# 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 + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + 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 + + ;; + 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 + { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # 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 sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# 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'" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +exec 6>&1 + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_config_libobj_dir=. +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Maximum number of lines to put in a shell here document. +# This variable seems obsolete. It should probably be removed, and +# only ac_max_sed_lines should be used. +: ${ac_max_here_lines=38} + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= + +ac_unique_file="src/main.c" +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO SET_MAKE CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT RANLIB ac_ct_RANLIB UI_OBJS CURSES_LIB SDL_CONFIG SDL_CFLAGS SDL_LIBS LIBOBJS LTLIBOBJS' +ac_subst_files='' + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# 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. +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +ac_prev= +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 + + ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_option in + + -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 | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + eval "enable_$ac_feature=no" ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "enable_$ac_feature='$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 ;; + + -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 ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + 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 ;; + + -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_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package| sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "with_$ac_package='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/-/_/g'` + eval "with_$ac_package=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 ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` + eval "$ac_envvar='$ac_optarg'" + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + 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'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute paths. +for ac_var in exec_prefix prefix +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* | NONE | '' ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# Be sure to have absolute paths. +for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ + localstatedir libdir includedir oldincludedir infodir mandir +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +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 + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + 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 + + +# 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 its parent. + ac_confdir=`(dirname "$0") 2>/dev/null || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$0" | + 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 + if test "$ac_srcdir_defaulted" = yes; then + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 + { (exit 1); exit 1; }; } + else + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } + fi +fi +(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || + { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 + { (exit 1); exit 1; }; } +srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` +ac_env_build_alias_set=${build_alias+set} +ac_env_build_alias_value=$build_alias +ac_cv_env_build_alias_set=${build_alias+set} +ac_cv_env_build_alias_value=$build_alias +ac_env_host_alias_set=${host_alias+set} +ac_env_host_alias_value=$host_alias +ac_cv_env_host_alias_set=${host_alias+set} +ac_cv_env_host_alias_value=$host_alias +ac_env_target_alias_set=${target_alias+set} +ac_env_target_alias_value=$target_alias +ac_cv_env_target_alias_set=${target_alias+set} +ac_cv_env_target_alias_value=$target_alias +ac_env_CC_set=${CC+set} +ac_env_CC_value=$CC +ac_cv_env_CC_set=${CC+set} +ac_cv_env_CC_value=$CC +ac_env_CFLAGS_set=${CFLAGS+set} +ac_env_CFLAGS_value=$CFLAGS +ac_cv_env_CFLAGS_set=${CFLAGS+set} +ac_cv_env_CFLAGS_value=$CFLAGS +ac_env_LDFLAGS_set=${LDFLAGS+set} +ac_env_LDFLAGS_value=$LDFLAGS +ac_cv_env_LDFLAGS_set=${LDFLAGS+set} +ac_cv_env_LDFLAGS_value=$LDFLAGS +ac_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_env_CPPFLAGS_value=$CPPFLAGS +ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_cv_env_CPPFLAGS_value=$CPPFLAGS + +# +# 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 this package 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 \`..'] + +_ACEOF + + cat <<_ACEOF +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] + --datadir=DIR read-only architecture-independent data [PREFIX/share] + --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] + --infodir=DIR info documentation [PREFIX/info] + --mandir=DIR man documentation [PREFIX/man] +_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] + --target=TARGET configure for building compilers for TARGET [HOST] +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Optional Features: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-sdltest Do not try to compile and run a test SDL program + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-sdl-prefix=PFX Prefix where SDL is installed (optional) + --with-sdl-exec-prefix=PFX Exec prefix where SDL is installed (optional) + +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 + CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have + headers in a nonstandard directory + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +_ACEOF +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + ac_popdir=`pwd` + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d $ac_dir || continue + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + cd $ac_dir + # Check for guested configure; otherwise get Cygnus style 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 + elif test -f $ac_srcdir/configure.ac || + test -f $ac_srcdir/configure.in; then + echo + $ac_configure --help + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi + cd "$ac_popdir" + done +fi + +test -n "$ac_init_help" && exit 0 +if $ac_init_version; then + cat <<\_ACEOF + +Copyright (C) 2003 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 0 +fi +exec 5>config.log +cat >&5 <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.59. Invocation command line was + + $ $0 $@ + +_ACEOF +{ +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` +hostinfo = `(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=. + echo "PATH: $as_dir" +done + +} >&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_sep= +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=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$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 + ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" + # Get rid of the leading space. + ac_sep=" " + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export 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: Be sure not to use single quotes in there, as some shells, +# such as our DU 5.0 friend, will then `close' the trap. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +{ + (set) 2>&1 | + case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in + *ac_space=\ *) + sed -n \ + "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" + ;; + *) + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------- ## +## Output files. ## +## ------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + sed "/^$/d" confdefs.h | sort + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core && + rm -rf conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status + ' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo >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 + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + 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. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . $cache_file;; + *) . ./$cache_file;; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +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 `(set) 2>&1 | + sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; 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,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +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 + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=$ac_var=`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. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +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_aux_dir= +for ac_dir in config $srcdir/config; 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 + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in config $srcdir/config" >&5 +echo "$as_me: error: cannot find install-sh or install.sh in config $srcdir/config" >&2;} + { (exit 1); exit 1; }; } +fi +ac_config_guess="$SHELL $ac_aux_dir/config.guess" +ac_config_sub="$SHELL $ac_aux_dir/config.sub" +ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. + + + ac_config_headers="$ac_config_headers config.h" + + ac_config_commands="$ac_config_commands default-1" + + +# Make sure we can run config.sub. +$ac_config_sub sun4 >/dev/null 2>&1 || + { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5 +echo "$as_me: error: cannot run $ac_config_sub" >&2;} + { (exit 1); exit 1; }; } + +echo "$as_me:$LINENO: checking build system type" >&5 +echo $ECHO_N "checking build system type... $ECHO_C" >&6 +if test "${ac_cv_build+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_build_alias=$build_alias +test -z "$ac_cv_build_alias" && + ac_cv_build_alias=`$ac_config_guess` +test -z "$ac_cv_build_alias" && + { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 +echo "$as_me: error: cannot guess build type; you must specify one" >&2;} + { (exit 1); exit 1; }; } +ac_cv_build=`$ac_config_sub $ac_cv_build_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_build" >&5 +echo "${ECHO_T}$ac_cv_build" >&6 +build=$ac_cv_build +build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + +echo "$as_me:$LINENO: checking host system type" >&5 +echo $ECHO_N "checking host system type... $ECHO_C" >&6 +if test "${ac_cv_host+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_host_alias=$host_alias +test -z "$ac_cv_host_alias" && + ac_cv_host_alias=$ac_cv_build_alias +ac_cv_host=`$ac_config_sub $ac_cv_host_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_host" >&5 +echo "${ECHO_T}$ac_cv_host" >&6 +host=$ac_cv_host +host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + +echo "$as_me:$LINENO: checking target system type" >&5 +echo $ECHO_N "checking target system type... $ECHO_C" >&6 +if test "${ac_cv_target+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_target_alias=$target_alias +test "x$ac_cv_target_alias" = "x" && + ac_cv_target_alias=$ac_cv_host_alias +ac_cv_target=`$ac_config_sub $ac_cv_target_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_target_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_target_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_target" >&5 +echo "${ECHO_T}$ac_cv_target" >&6 +target=$ac_cv_target +target_cpu=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +target_vendor=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +target_os=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +test -n "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + +am__api_version="1.4" +# 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. +echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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_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 + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done + + +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. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL=$ac_install_sh + fi +fi +echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$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' + +echo "$as_me:$LINENO: checking whether build environment is sane" >&5 +echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6 +# Just in case +sleep 1 +echo timestamp > conftestfile +# 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 ( + set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftestfile` + fi + if test "$*" != "X $srcdir/configure conftestfile" \ + && test "$*" != "X conftestfile $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". + { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&5 +echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&2;} + { (exit 1); exit 1; }; } + fi + + test "$2" = conftestfile + ) +then + # Ok. + : +else + { { echo "$as_me:$LINENO: error: newly created file is older than distributed files! +Check your system clock" >&5 +echo "$as_me: error: newly created file is older than distributed files! +Check your system clock" >&2;} + { (exit 1); exit 1; }; } +fi +rm -f conftest* +echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +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 $. echo might interpret backslashes. +# By default was `s,x,x', remove it if useless. +cat <<\_ACEOF >conftest.sed +s/[\\$]/&&/g;s/;s,x,x,$// +_ACEOF +program_transform_name=`echo $program_transform_name | sed -f conftest.sed` +rm conftest.sed + +echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'` +if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.make <<\_ACEOF +all: + @echo 'ac_maketemp="$(MAKE)"' +_ACEOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftest.make +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + SET_MAKE= +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + + +PACKAGE=emuriver + +VERSION=0.3 + +if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then + { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 +echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} + { (exit 1); exit 1; }; } +fi + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + + + +missing_dir=`cd $ac_aux_dir && pwd` +echo "$as_me:$LINENO: checking for working aclocal-${am__api_version}" >&5 +echo $ECHO_N "checking for working aclocal-${am__api_version}... $ECHO_C" >&6 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (aclocal-${am__api_version} --version) < /dev/null > /dev/null 2>&1; then + ACLOCAL=aclocal-${am__api_version} + echo "$as_me:$LINENO: result: found" >&5 +echo "${ECHO_T}found" >&6 +else + ACLOCAL="$missing_dir/missing aclocal-${am__api_version}" + echo "$as_me:$LINENO: result: missing" >&5 +echo "${ECHO_T}missing" >&6 +fi + +echo "$as_me:$LINENO: checking for working autoconf" >&5 +echo $ECHO_N "checking for working autoconf... $ECHO_C" >&6 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (autoconf --version) < /dev/null > /dev/null 2>&1; then + AUTOCONF=autoconf + echo "$as_me:$LINENO: result: found" >&5 +echo "${ECHO_T}found" >&6 +else + AUTOCONF="$missing_dir/missing autoconf" + echo "$as_me:$LINENO: result: missing" >&5 +echo "${ECHO_T}missing" >&6 +fi + +echo "$as_me:$LINENO: checking for working automake-${am__api_version}" >&5 +echo $ECHO_N "checking for working automake-${am__api_version}... $ECHO_C" >&6 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (automake-${am__api_version} --version) < /dev/null > /dev/null 2>&1; then + AUTOMAKE=automake-${am__api_version} + echo "$as_me:$LINENO: result: found" >&5 +echo "${ECHO_T}found" >&6 +else + AUTOMAKE="$missing_dir/missing automake-${am__api_version}" + echo "$as_me:$LINENO: result: missing" >&5 +echo "${ECHO_T}missing" >&6 +fi + +echo "$as_me:$LINENO: checking for working autoheader" >&5 +echo $ECHO_N "checking for working autoheader... $ECHO_C" >&6 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (autoheader --version) < /dev/null > /dev/null 2>&1; then + AUTOHEADER=autoheader + echo "$as_me:$LINENO: result: found" >&5 +echo "${ECHO_T}found" >&6 +else + AUTOHEADER="$missing_dir/missing autoheader" + echo "$as_me:$LINENO: result: missing" >&5 +echo "${ECHO_T}missing" >&6 +fi + +echo "$as_me:$LINENO: checking for working makeinfo" >&5 +echo $ECHO_N "checking for working makeinfo... $ECHO_C" >&6 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (makeinfo --version) < /dev/null > /dev/null 2>&1; then + MAKEINFO=makeinfo + echo "$as_me:$LINENO: result: found" >&5 +echo "${ECHO_T}found" >&6 +else + MAKEINFO="$missing_dir/missing makeinfo" + echo "$as_me:$LINENO: result: missing" >&5 +echo "${ECHO_T}missing" >&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 +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 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}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 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +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 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +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 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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_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" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +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 + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl + 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 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_CC" && break +done + + CC=$ac_ct_CC +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO:" \ + "checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 + (eval $ac_compiler --version &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 + (eval $ac_compiler -v &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 + (eval $ac_compiler -V &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out 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. +echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6 +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 + (eval $ac_link_default) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Find the output, starting from the most likely. This scheme is +# not robust to junk in `.', hence go to wildcards (a.*) only as a last +# resort. + +# Be careful to initialize this variable, since it used to be cached. +# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. +ac_cv_exeext= +# b.out is created by i960 compilers. +for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) + ;; + conftest.$ac_ext ) + # This is the source file. + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + # FIXME: I believe we export ac_cv_exeext for Libtool, + # but it would be cool to find out if it's true. Does anybody + # maintain Libtool? --akim. + export ac_cv_exeext + break;; + * ) + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6 + +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +rm -f a.out a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6 + +echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; 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 | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + export ac_cv_exeext + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6 + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6 +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_compiler_gnu=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +CFLAGS="-g" +echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_prog_cc_g=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$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 +echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 +echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_stdc=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* 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 -std1 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 -std1. */ +int osf4_cc_array ['\x00' == 0 ? 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 +# Don't try gcc -ansi; that turns off useful extensions and +# breaks some systems' header files. +# AIX -qlanglvl=ansi +# Ultrix and OSF/1 -std1 +# HP-UX 10.20 and later -Ae +# HP-UX older versions -Aa -D_HPUX_SOURCE +# SVR4 -Xc -D__EXTENSIONS__ +for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_stdc=$ac_arg +break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext +done +rm -f conftest.$ac_ext conftest.$ac_objext +CC=$ac_save_CC + +fi + +case "x$ac_cv_prog_cc_stdc" in + x|xno) + echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6 ;; + *) + echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 + CC="$CC $ac_cv_prog_cc_stdc" ;; +esac + +# Some people use a C++ compiler to compile C. Since we use `exit', +# in C++ we need to declare it. In case someone uses the same compiler +# for both compiling C and C++ we need to have the C++ compiler decide +# the declaration of exit, since it's the most demanding environment. +cat >conftest.$ac_ext <<_ACEOF +#ifndef __cplusplus + choke me +#endif +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + for ac_declaration in \ + '' \ + 'extern "C" void std::exit (int) throw (); using std::exit;' \ + 'extern "C" void std::exit (int); using std::exit;' \ + 'extern "C" void exit (int) throw ();' \ + 'extern "C" void exit (int);' \ + 'void exit (int);' +do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +#include +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +continue +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +done +rm -f conftest* +if test -n "$ac_declaration"; then + echo '#ifdef __cplusplus' >>confdefs.h + echo $ac_declaration >>confdefs.h + echo '#endif' >>confdefs.h +fi + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext 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 + +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 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + echo "$as_me:$LINENO: result: $RANLIB" >&5 +echo "${ECHO_T}$RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}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 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 +echo "${ECHO_T}$ac_ct_RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + RANLIB=$ac_ct_RANLIB +else + RANLIB="$ac_cv_prog_RANLIB" +fi + + + +echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5 +echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6 +if test "${ac_cv_c_bigendian+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # See if sys/param.h defines the BYTE_ORDER macro. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include + +int +main () +{ +#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN + bogus endian macros +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + # It does; now see whether it defined to BIG_ENDIAN or not. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include + +int +main () +{ +#if BYTE_ORDER != BIG_ENDIAN + not big endian +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_bigendian=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_c_bigendian=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +# It does not; compile a test program. +if test "$cross_compiling" = yes; then + # try to guess the endianness by grepping values into an object file + ac_cv_c_bigendian=unknown + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; +short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; +void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; } +short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; +short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; +void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; } +int +main () +{ + _ascii (); _ebcdic (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then + ac_cv_c_bigendian=yes +fi +if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then + if test "$ac_cv_c_bigendian" = unknown; then + ac_cv_c_bigendian=no + else + # finding both strings is unlikely to happen, but who knows? + ac_cv_c_bigendian=unknown + fi +fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +int +main () +{ + /* Are we little or big endian? From Harbison&Steele. */ + union + { + long l; + char c[sizeof (long)]; + } u; + u.l = 1; + exit (u.c[sizeof (long) - 1] == 1); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_bigendian=no +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_c_bigendian=yes +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5 +echo "${ECHO_T}$ac_cv_c_bigendian" >&6 +case $ac_cv_c_bigendian in + yes) + bigendian=yes ;; + no) + bigendian=no ;; + *) + { { echo "$as_me:$LINENO: error: cannot determine endianess" >&5 +echo "$as_me: error: cannot determine endianess" >&2;} + { (exit 1); exit 1; }; } ;; +esac + +if test "$bigendian" = yes +then + +cat >>confdefs.h <<\_ACEOF +#define CONFIG_BIGENDIAN +_ACEOF + +fi + +UI_OBJS="" + + + +save_LIBS=$LIBS +CURSES_LIB="" +echo "$as_me:$LINENO: checking for working curses" >&5 +echo $ECHO_N "checking for working curses... $ECHO_C" >&6 +if test "${curses+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + LIBS="$LIBS -lcurses" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ +chtype a; int b=A_STANDOUT, c=KEY_LEFT; initscr(); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + curses=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +curses=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $curses" >&5 +echo "${ECHO_T}$curses" >&6 +if test "$curses" = yes +then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_CURSES_H +_ACEOF + + CURSES_LIB="-lcurses" +fi +if test ! "$CURSES_LIB" +then + echo "$as_me:$LINENO: checking for working ncurses" >&5 +echo $ECHO_N "checking for working ncurses... $ECHO_C" >&6 +if test "${ncurses+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + LIBS="$save_LIBS -lncurses" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ +chtype a; int b=A_STANDOUT, c=KEY_LEFT; initscr(); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ncurses=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ncurses=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ncurses" >&5 +echo "${ECHO_T}$ncurses" >&6 + if test "$ncurses" = yes + then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_NCURSES_H +_ACEOF + + CURSES_LIB="-lncurses" + fi +fi +if test ! "$CURSES_LIB" +then + { { echo "$as_me:$LINENO: error: no curses library found" >&5 +echo "$as_me: error: no curses library found" >&2;} + { (exit 1); exit 1; }; } +else + UI_OBJS="$UI_OBJS uicurses.o" +fi +LIBS="$save_LIBS" + + +# Check whether --with-sdl-prefix or --without-sdl-prefix was given. +if test "${with_sdl_prefix+set}" = set; then + withval="$with_sdl_prefix" + sdl_prefix="$withval" +else + sdl_prefix="" +fi; + +# Check whether --with-sdl-exec-prefix or --without-sdl-exec-prefix was given. +if test "${with_sdl_exec_prefix+set}" = set; then + withval="$with_sdl_exec_prefix" + sdl_exec_prefix="$withval" +else + sdl_exec_prefix="" +fi; +# Check whether --enable-sdltest or --disable-sdltest was given. +if test "${enable_sdltest+set}" = set; then + enableval="$enable_sdltest" + +else + enable_sdltest=yes +fi; + + if test x$sdl_exec_prefix != x ; then + sdl_args="$sdl_args --exec-prefix=$sdl_exec_prefix" + if test x${SDL_CONFIG+set} != xset ; then + SDL_CONFIG=$sdl_exec_prefix/bin/sdl-config + fi + fi + if test x$sdl_prefix != x ; then + sdl_args="$sdl_args --prefix=$sdl_prefix" + if test x${SDL_CONFIG+set} != xset ; then + SDL_CONFIG=$sdl_prefix/bin/sdl-config + fi + fi + + + PATH="$prefix/bin:$prefix/usr/bin:$PATH" + # Extract the first word of "sdl-config", so it can be a program name with args. +set dummy sdl-config; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_path_SDL_CONFIG+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $SDL_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_SDL_CONFIG="$SDL_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_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_SDL_CONFIG="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_path_SDL_CONFIG" && ac_cv_path_SDL_CONFIG="no" + ;; +esac +fi +SDL_CONFIG=$ac_cv_path_SDL_CONFIG + +if test -n "$SDL_CONFIG"; then + echo "$as_me:$LINENO: result: $SDL_CONFIG" >&5 +echo "${ECHO_T}$SDL_CONFIG" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + min_sdl_version=1.2.7 + echo "$as_me:$LINENO: checking for SDL - version >= $min_sdl_version" >&5 +echo $ECHO_N "checking for SDL - version >= $min_sdl_version... $ECHO_C" >&6 + no_sdl="" + if test "$SDL_CONFIG" = "no" ; then + no_sdl=yes + else + SDL_CFLAGS=`$SDL_CONFIG $sdlconf_args --cflags` + SDL_LIBS=`$SDL_CONFIG $sdlconf_args --libs` + + sdl_major_version=`$SDL_CONFIG $sdl_args --version | \ + sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\1/'` + sdl_minor_version=`$SDL_CONFIG $sdl_args --version | \ + sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\2/'` + sdl_micro_version=`$SDL_CONFIG $sdl_config_args --version | \ + sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\3/'` + if test "x$enable_sdltest" = "xyes" ; then + ac_save_CFLAGS="$CFLAGS" + ac_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $SDL_CFLAGS" + LIBS="$LIBS $SDL_LIBS" + rm -f conf.sdltest + if test "$cross_compiling" = yes; then + echo $ac_n "cross compiling; assumed OK... $ac_c" +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#include +#include +#include "SDL.h" + +char* +my_strdup (char *str) +{ + char *new_str; + + if (str) + { + new_str = (char *)malloc ((strlen (str) + 1) * sizeof(char)); + strcpy (new_str, str); + } + else + new_str = NULL; + + return new_str; +} + +int main (int argc, char *argv[]) +{ + int major, minor, micro; + char *tmp_version; + + /* This hangs on some systems (?) + system ("touch conf.sdltest"); + */ + { FILE *fp = fopen("conf.sdltest", "a"); if ( fp ) fclose(fp); } + + /* HP/UX 9 (%@#!) writes to sscanf strings */ + tmp_version = my_strdup("$min_sdl_version"); + if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { + printf("%s, bad version string\n", "$min_sdl_version"); + exit(1); + } + + if (($sdl_major_version > major) || + (($sdl_major_version == major) && ($sdl_minor_version > minor)) || + (($sdl_major_version == major) && ($sdl_minor_version == minor) && ($sdl_micro_version >= micro))) + { + return 0; + } + else + { + printf("\n*** 'sdl-config --version' returned %d.%d.%d, but the minimum version\n", $sdl_major_version, $sdl_minor_version, $sdl_micro_version); + printf("*** of SDL required is %d.%d.%d. If sdl-config is correct, then it is\n", major, minor, micro); + printf("*** best to upgrade to the required version.\n"); + printf("*** If sdl-config was wrong, set the environment variable SDL_CONFIG\n"); + printf("*** to point to the correct copy of sdl-config, and remove the file\n"); + printf("*** config.cache before re-running configure\n"); + return 1; + } +} + + +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +no_sdl=yes +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + if test "x$no_sdl" = x ; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + havesdl=yes + else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + if test "$SDL_CONFIG" = "no" ; then + echo "*** The sdl-config script installed by SDL could not be found" + echo "*** If SDL was installed in PREFIX, make sure PREFIX/bin is in" + echo "*** your path, or set the SDL_CONFIG environment variable to the" + echo "*** full path to sdl-config." + else + if test -f conf.sdltest ; then + : + else + echo "*** Could not run SDL test program, checking why..." + CFLAGS="$CFLAGS $SDL_CFLAGS" + LIBS="$LIBS $SDL_LIBS" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#include "SDL.h" + +int main(int argc, char *argv[]) +{ return 0; } +#undef main +#define main K_and_R_C_main + +int +main () +{ + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + echo "*** The test program compiled, but did not run. This usually means" + echo "*** that the run-time linker is not finding SDL or finding the wrong" + echo "*** version of SDL. If it is not finding SDL, you'll need to set your" + echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" + echo "*** to the installed location Also, make sure you have run ldconfig if that" + echo "*** is required on your system" + echo "***" + echo "*** If you have an old version installed, it is best to remove it, although" + echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + echo "*** The test program failed to compile or link. See the file config.log for the" + echo "*** exact error that occured. This usually means SDL was incorrectly installed" + echo "*** or that you have moved SDL since it was installed. In the latter case, you" + echo "*** may want to edit the sdl-config script: $SDL_CONFIG" +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + SDL_CFLAGS="" + SDL_LIBS="" + havesdl=no + fi + + + rm -f conf.sdltest + +if test $havesdl = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_SDL +_ACEOF + + UI_OBJS="$UI_OBJS uisdl.o" +fi + + + ac_config_files="$ac_config_files Makefile src/Makefile src/flashimgtool/Makefile src/common/Makefile" +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, don't put newlines in cache variables' values. +# 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. +{ + (set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *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 \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} | + sed ' + t clear + : clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + : end' >>confcache +if diff $cache_file confcache >/dev/null 2>&1; then :; else + if test -w $cache_file; then + test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" + cat confcache >$cache_file + else + echo "not updating unwritable cache $cache_file" + 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}' + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ 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[ ]*=/{ +s/:*\$(srcdir):*/:/; +s/:*\${srcdir}:*/:/; +s/:*@srcdir@:*/:/; +s/^\([^=]*=[ ]*\):*/\1/; +s/:*$//; +s/^[^=]*=[ ]*$//; +}' +fi + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_i=`echo "$ac_i" | + sed 's/\$U\././;s/\.o$//;s/\.obj$//'` + # 2. Add them. + ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $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} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# 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+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi +DUALCASE=1; export DUALCASE # for MKS sh + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; 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 + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# 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 + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + 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 + + ;; + 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 + { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 +echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 +echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} + { (exit 1); exit 1; }; } + + # 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 sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# 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'" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + +exec 6>&1 + +# Open the log real soon, to keep \$[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. Logging --version etc. is OK. +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX +} >&5 +cat >&5 <<_CSEOF + +This file was extended by $as_me, which was +generated by GNU Autoconf 2.59. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +_CSEOF +echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 +echo >&5 +_ACEOF + +# Files that config.status was made for. +if test -n "$ac_config_files"; then + echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_headers"; then + echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_links"; then + echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_commands"; then + echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS +fi + +cat >>$CONFIG_STATUS <<\_ACEOF + +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -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 + --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_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.59, + with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2003 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." +srcdir=$srcdir +INSTALL="$INSTALL" +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +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=$1 + ac_optarg=$2 + ac_shift=shift + ;; + *) # This is not an option, so the user has probably given explicit + # arguments. + ac_option=$1 + ac_need_defaults=false;; + esac + + case $ac_option in + # Handling of the options. +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --vers* | -V ) + echo "$ac_cs_version"; exit 0 ;; + --he | --h) + # Conflict between --help and --header + { { echo "$as_me:$LINENO: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" ;; + + 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 +if \$ac_cs_recheck; then + echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +# +# INIT-COMMANDS section. +# + + + +_ACEOF + + + +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_config_target in $ac_config_targets +do + case "$ac_config_target" in + # Handling of arguments. + "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "src/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; + "src/flashimgtool/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/flashimgtool/Makefile" ;; + "src/common/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/common/Makefile" ;; + "default-1" ) CONFIG_COMMANDS="$CONFIG_COMMANDS default-1" ;; + "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + 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 to put it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./confstat$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF + +# +# CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "\$CONFIG_FILES"; then + # Protect against being on the right side of a sed subst in config.status. + sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; + s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF +s,@SHELL@,$SHELL,;t t +s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t +s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t +s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t +s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t +s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t +s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t +s,@exec_prefix@,$exec_prefix,;t t +s,@prefix@,$prefix,;t t +s,@program_transform_name@,$program_transform_name,;t t +s,@bindir@,$bindir,;t t +s,@sbindir@,$sbindir,;t t +s,@libexecdir@,$libexecdir,;t t +s,@datadir@,$datadir,;t t +s,@sysconfdir@,$sysconfdir,;t t +s,@sharedstatedir@,$sharedstatedir,;t t +s,@localstatedir@,$localstatedir,;t t +s,@libdir@,$libdir,;t t +s,@includedir@,$includedir,;t t +s,@oldincludedir@,$oldincludedir,;t t +s,@infodir@,$infodir,;t t +s,@mandir@,$mandir,;t t +s,@build_alias@,$build_alias,;t t +s,@host_alias@,$host_alias,;t t +s,@target_alias@,$target_alias,;t t +s,@DEFS@,$DEFS,;t t +s,@ECHO_C@,$ECHO_C,;t t +s,@ECHO_N@,$ECHO_N,;t t +s,@ECHO_T@,$ECHO_T,;t t +s,@LIBS@,$LIBS,;t t +s,@build@,$build,;t t +s,@build_cpu@,$build_cpu,;t t +s,@build_vendor@,$build_vendor,;t t +s,@build_os@,$build_os,;t t +s,@host@,$host,;t t +s,@host_cpu@,$host_cpu,;t t +s,@host_vendor@,$host_vendor,;t t +s,@host_os@,$host_os,;t t +s,@target@,$target,;t t +s,@target_cpu@,$target_cpu,;t t +s,@target_vendor@,$target_vendor,;t t +s,@target_os@,$target_os,;t t +s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t +s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t +s,@INSTALL_DATA@,$INSTALL_DATA,;t t +s,@PACKAGE@,$PACKAGE,;t t +s,@VERSION@,$VERSION,;t t +s,@ACLOCAL@,$ACLOCAL,;t t +s,@AUTOCONF@,$AUTOCONF,;t t +s,@AUTOMAKE@,$AUTOMAKE,;t t +s,@AUTOHEADER@,$AUTOHEADER,;t t +s,@MAKEINFO@,$MAKEINFO,;t t +s,@SET_MAKE@,$SET_MAKE,;t t +s,@CC@,$CC,;t t +s,@CFLAGS@,$CFLAGS,;t t +s,@LDFLAGS@,$LDFLAGS,;t t +s,@CPPFLAGS@,$CPPFLAGS,;t t +s,@ac_ct_CC@,$ac_ct_CC,;t t +s,@EXEEXT@,$EXEEXT,;t t +s,@OBJEXT@,$OBJEXT,;t t +s,@RANLIB@,$RANLIB,;t t +s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t +s,@UI_OBJS@,$UI_OBJS,;t t +s,@CURSES_LIB@,$CURSES_LIB,;t t +s,@SDL_CONFIG@,$SDL_CONFIG,;t t +s,@SDL_CFLAGS@,$SDL_CFLAGS,;t t +s,@SDL_LIBS@,$SDL_LIBS,;t t +s,@LIBOBJS@,$LIBOBJS,;t t +s,@LTLIBOBJS@,$LTLIBOBJS,;t t +CEOF + +_ACEOF + + cat >>$CONFIG_STATUS <<\_ACEOF + # Split the substitutions into bite-sized pieces for seds with + # small command number limits, like on Digital OSF/1 and HP-UX. + ac_max_sed_lines=48 + ac_sed_frag=1 # Number of current file. + ac_beg=1 # First line for current file. + ac_end=$ac_max_sed_lines # Line after last line for current file. + ac_more_lines=: + ac_sed_cmds= + while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + else + sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + fi + if test ! -s $tmp/subs.frag; then + ac_more_lines=false + else + # The purpose of the label and of the branching condition is to + # speed up the sed processing (if there are no `@' at all, there + # is no need to browse any of the substitutions). + # These are the two extra sed commands mentioned above. + (echo ':t + /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" + else + ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" + fi + ac_sed_frag=`expr $ac_sed_frag + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_lines` + fi + done + if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat + fi +fi # test -n "$CONFIG_FILES" + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_builddir$INSTALL ;; + esac + + # 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. */ + if test x"$ac_file" = x-; then + configure_input= + else + configure_input="$ac_file. " + fi + configure_input=$configure_input"Generated from `echo $ac_file_in | + sed 's,.*/,,'` by configure." + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo "$f";; + *) # Relative + if test -f "$f"; then + # Build tree + echo "$f" + elif test -f "$srcdir/$f"; then + # Source tree + echo "$srcdir/$f" + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } + + if test x"$ac_file" != x-; then + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + rm -f "$ac_file" + fi +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s,@configure_input@,$configure_input,;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,@top_builddir@,$ac_top_builddir,;t t +s,@abs_top_builddir@,$ac_abs_top_builddir,;t t +s,@INSTALL@,$ac_INSTALL,;t t +" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out + rm -f $tmp/stdin + if test x"$ac_file" != x-; then + mv $tmp/out $ac_file + else + cat $tmp/out + rm -f $tmp/out + fi + +done +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + +# +# CONFIG_HEADER section. +# + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='[ ].*$,\1#\2' +ac_dC=' ' +ac_dD=',;t' +# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='$,\1#\2define\3' +ac_uC=' ' +ac_uD=',;t' + +for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + # Do quote $f, to prevent DOS paths from being IFS'd. + echo "$f";; + *) # Relative + if test -f "$f"; then + # Build tree + echo "$f" + elif test -f "$srcdir/$f"; then + # Source tree + echo "$srcdir/$f" + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } + # Remove the trailing spaces. + sed 's/[ ]*$//' $ac_file_inputs >$tmp/in + +_ACEOF + +# Transform confdefs.h into two sed scripts, `conftest.defines' and +# `conftest.undefs', that substitutes the proper values into +# config.h.in to produce config.h. The first handles `#define' +# templates, and the second `#undef' templates. +# And first: Protect against being on the right side of a sed subst in +# config.status. Protect against being in an unquoted here document +# in config.status. +rm -f conftest.defines conftest.undefs +# Using a here document instead of a string reduces the quoting nightmare. +# Putting comments in sed scripts is not portable. +# +# `end' is used to avoid that the second main sed command (meant for +# 0-ary CPP macros) applies to n-ary macro definitions. +# See the Autoconf documentation for `clear'. +cat >confdef2sed.sed <<\_ACEOF +s/[\\&,]/\\&/g +s,[\\$`],\\&,g +t clear +: clear +s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp +t end +s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp +: end +_ACEOF +# If some macros were called several times there might be several times +# the same #defines, which is useless. Nevertheless, we may not want to +# sort them, since we want the *last* AC-DEFINE to be honored. +uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines +sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs +rm -f confdef2sed.sed + +# This sed command replaces #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. +cat >>conftest.undefs <<\_ACEOF +s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, +_ACEOF + +# Break up conftest.defines because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS +echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS +echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS +echo ' :' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.defines >/dev/null +do + # Write a limited-size here document to $tmp/defines.sed. + echo ' cat >$tmp/defines.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#define' lines. + echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/defines.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail + rm -f conftest.defines + mv conftest.tail conftest.defines +done +rm -f conftest.defines +echo ' fi # grep' >>$CONFIG_STATUS +echo >>$CONFIG_STATUS + +# Break up conftest.undefs because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #undef templates' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.undefs >/dev/null +do + # Write a limited-size here document to $tmp/undefs.sed. + echo ' cat >$tmp/undefs.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#undef' + echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/undefs.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail + rm -f conftest.undefs + mv conftest.tail conftest.undefs +done +rm -f conftest.undefs + +cat >>$CONFIG_STATUS <<\_ACEOF + # 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. */ + if test x"$ac_file" = x-; then + echo "/* Generated by configure. */" >$tmp/config.h + else + echo "/* $ac_file. Generated by configure. */" >$tmp/config.h + fi + cat $tmp/in >>$tmp/config.h + rm -f $tmp/in + if test x"$ac_file" != x-; then + if diff $ac_file $tmp/config.h >/dev/null 2>&1; then + { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + rm -f $ac_file + mv $tmp/config.h $ac_file + fi + else + cat $tmp/config.h + rm -f $tmp/config.h + fi +done +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + +# +# CONFIG_COMMANDS section. +# +for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue + ac_dest=`echo "$ac_file" | sed 's,:.*,,'` + ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_dir=`(dirname "$ac_dest") 2>/dev/null || +$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_dest" : 'X\(//\)[^/]' \| \ + X"$ac_dest" : 'X\(//\)$' \| \ + X"$ac_dest" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_dest" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + + { echo "$as_me:$LINENO: executing $ac_dest commands" >&5 +echo "$as_me: executing $ac_dest commands" >&6;} + case $ac_dest in + default-1 ) test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h ;; + esac +done +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# 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 || { (exit 1); exit 1; } +fi + Egenskapsändringar för: utils/emuriver/configure ___________________________________________________________________ Added: svn:executable + * Index: utils/emuriver/Makefile.in =================================================================== --- utils/emuriver/Makefile.in (revision 0) +++ utils/emuriver/Makefile.in (revision 0) @@ -0,0 +1,360 @@ +# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999, 2001 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. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = . + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +CC = @CC@ +CURSES_LIB = @CURSES_LIB@ +HAVE_LIB = @HAVE_LIB@ +LIB = @LIB@ +LTLIB = @LTLIB@ +MAKEINFO = @MAKEINFO@ +PACKAGE = @PACKAGE@ +RANLIB = @RANLIB@ +SDL_CFLAGS = @SDL_CFLAGS@ +SDL_CONFIG = @SDL_CONFIG@ +SDL_LIBS = @SDL_LIBS@ +UI_OBJS = @UI_OBJS@ +VERSION = @VERSION@ + +SUBDIRS = src + +EXTRA_DIST = gdb_scripts config +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = +DIST_COMMON = README ./stamp-h.in AUTHORS COPYING ChangeLog INSTALL \ +Makefile.am Makefile.in NEWS TODO aclocal.m4 config.h.in configure \ +configure.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP_ENV = --best +all: all-redirect +.SUFFIXES: +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status + +$(ACLOCAL_M4): configure.in + cd $(srcdir) && $(ACLOCAL) + +config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck +$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) + cd $(srcdir) && $(AUTOCONF) + +config.h: stamp-h + @if test ! -f $@; then \ + rm -f stamp-h; \ + $(MAKE) stamp-h; \ + else :; fi +stamp-h: $(srcdir)/config.h.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES= CONFIG_HEADERS=config.h \ + $(SHELL) ./config.status + @echo timestamp > stamp-h 2> /dev/null +$(srcdir)/config.h.in: $(srcdir)/stamp-h.in + @if test ! -f $@; then \ + rm -f $(srcdir)/stamp-h.in; \ + $(MAKE) $(srcdir)/stamp-h.in; \ + else :; fi +$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOHEADER) + @echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null + +mostlyclean-hdr: + +clean-hdr: + +distclean-hdr: + -rm -f config.h + +maintainer-clean-hdr: + +# 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. + +@SET_MAKE@ + +all-recursive install-data-recursive install-exec-recursive \ +installdirs-recursive install-recursive uninstall-recursive \ +check-recursive installcheck-recursive info-recursive dvi-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; 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; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ + rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \ + rev="$$subdir $$rev"; \ + test "$$subdir" != "." || dot_seen=yes; \ + done; \ + test "$$dot_seen" = "no" && rev=". $$rev"; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)config.h.in$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags -o $$here/TAGS $(ETAGS_ARGS) $$tags config.h.in $$unique $(LISP)) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(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 + -rm -rf $(distdir) + GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz + mkdir $(distdir)/=build + mkdir $(distdir)/=inst + dc_install_base=`cd $(distdir)/=inst && pwd`; \ + cd $(distdir)/=build \ + && ../configure --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) dist + -rm -rf $(distdir) + @banner="$(distdir).tar.gz is ready for distribution"; \ + dashes=`echo "$$banner" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + echo "$$dashes" +dist: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +dist-all: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +distdir: $(DISTFILES) + -rm -rf $(distdir) + mkdir $(distdir) + -chmod 777 $(distdir) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + for subdir in $(SUBDIRS); do \ + if test "$$subdir" = .; then :; else \ + test -d $(distdir)/$$subdir \ + || mkdir $(distdir)/$$subdir \ + || exit 1; \ + chmod 777 $(distdir)/$$subdir; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \ + || exit 1; \ + fi; \ + done +info-am: +info: info-recursive +dvi-am: +dvi: dvi-recursive +check-am: all-am +check: check-recursive +installcheck-am: +installcheck: installcheck-recursive +all-recursive-am: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +install-exec-am: +install-exec: install-exec-recursive + +install-data-am: +install-data: install-data-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-recursive +uninstall-am: +uninstall: uninstall-recursive +all-am: Makefile config.h +all-redirect: all-recursive-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: installdirs-recursive +installdirs-am: + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-hdr mostlyclean-tags mostlyclean-generic + +mostlyclean: mostlyclean-recursive + +clean-am: clean-hdr clean-tags clean-generic mostlyclean-am + +clean: clean-recursive + +distclean-am: distclean-hdr distclean-tags distclean-generic clean-am + +distclean: distclean-recursive + -rm -f config.status + +maintainer-clean-am: maintainer-clean-hdr maintainer-clean-tags \ + maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-recursive + -rm -f config.status + +.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \ +install-data-recursive uninstall-data-recursive install-exec-recursive \ +uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \ +all-recursive check-recursive installcheck-recursive info-recursive \ +dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \ +maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir info-am info \ +dvi-am dvi check check-am installcheck-am installcheck all-recursive-am \ +install-exec-am install-exec install-data-am install-data install-am \ +install uninstall-am uninstall all-redirect all-am all installdirs-am \ +installdirs mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +# 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: Index: utils/emuriver/AUTHORS =================================================================== Index: utils/emuriver/configure.in =================================================================== --- utils/emuriver/configure.in (revision 0) +++ utils/emuriver/configure.in (revision 0) @@ -0,0 +1,67 @@ +AC_INIT(src/main.c) +AC_CONFIG_AUX_DIR(config) +AM_CONFIG_HEADER(config.h) + +AC_CANONICAL_HOST +AC_CANONICAL_TARGET + +AM_INIT_AUTOMAKE(emuriver, 0.3) + +AC_PROG_CC +AC_PROG_RANLIB + +AC_C_BIGENDIAN(bigendian=yes, bigendian=no, + AC_MSG_ERROR(cannot determine endianess)) +if test "$bigendian" = yes +then + AC_DEFINE([CONFIG_BIGENDIAN], [], [Define this if your system is big-endian]) +fi + +UI_OBJS="" +AC_SUBST(UI_OBJS) + +AC_SUBST(CURSES_LIB) +save_LIBS=$LIBS +CURSES_LIB="" +AC_CACHE_CHECK([for working curses], curses, + [LIBS="$LIBS -lcurses" + AC_TRY_LINK( + [#include ], + [chtype a; int b=A_STANDOUT, c=KEY_LEFT; initscr(); ], + curses=yes, curses=no)]) +if test "$curses" = yes +then + AC_DEFINE([HAVE_CURSES_H], [], [Define this if you have curses.h]) + CURSES_LIB="-lcurses" +fi +if test ! "$CURSES_LIB" +then + AC_CACHE_CHECK([for working ncurses], ncurses, + [LIBS="$save_LIBS -lncurses" + AC_TRY_LINK( + [#include ], + [chtype a; int b=A_STANDOUT, c=KEY_LEFT; initscr(); ], + ncurses=yes, ncurses=no)]) + if test "$ncurses" = yes + then + AC_DEFINE([HAVE_NCURSES_H], [], [Define this if you have ncurses.h]) + CURSES_LIB="-lncurses" + fi +fi +if test ! "$CURSES_LIB" +then + AC_MSG_ERROR(no curses library found) +else + UI_OBJS="$UI_OBJS uicurses.o" +fi +LIBS="$save_LIBS" + +AM_PATH_SDL(1.2.7, havesdl=yes, havesdl=no) +if test $havesdl = yes; then + AC_DEFINE([HAVE_SDL], [], [Define this if you have SDL]) + UI_OBJS="$UI_OBJS uisdl.o" +fi + + +AC_OUTPUT([Makefile src/Makefile src/flashimgtool/Makefile + src/common/Makefile]) Index: utils/emuriver/src/trace.c =================================================================== --- utils/emuriver/src/trace.c (revision 0) +++ utils/emuriver/src/trace.c (revision 0) @@ -0,0 +1,213 @@ +/* iRiver iFP 7XX Emulator + Copyright (C) 2005 Tomasz Malesinski + + 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 */ + +#include + +#include "trace.h" +#include "cpu.h" +#include "memory.h" +#include "log.h" + +static int link_stack[10000]; +static int nesting_level = 0; +static int quiet = 0; +static struct function *functions; +static int n_functions; +static uint32 last_pc, last_func; + +int stack_tracing; + +static struct function functions_empty[] = { + {0, NULL, 0, 0} +}; + +void trace_init(void) { + int i; + i = 0; + while (functions[i].adr != 0) i++; + n_functions = i; + last_pc = 0xdeadcafe; + stack_tracing = 1; +} + +static int trace_fw_strcmp(struct memory *mem, uint32 adr, char *s) { + while (*s) { + if (memory_read(mem, adr, NULL, 0) != *s) return 0; + s++; + adr++; + } + return 1; +} + +void trace_detect_firmware(struct memory *mem) { + functions = functions_empty; +} + +static int print_backtrace(char *s) { + int i, p, q; + sprintf(s, "["); + p = 1; + for (i = 0; i < nesting_level; i++) { + sprintf(s + p, "%x%c%n", link_stack[i], + i == nesting_level - 1 ? ']' : ' ', &q); + p += q; + } + return p; +} + +void trace_bl(struct cpu *cpu, int backtrace) { + char tmp[1000]; /* TODO may overflow */ + int i; + if (quiet) + return; + + if (stack_tracing) { + if (nesting_level > 30) return; + + link_stack[nesting_level++] = cpu->reg[14]; + + if (backtrace) { + int p = 0; + int q; + sprintf(tmp + p, + "bl to %8x %n", cpu->reg[15], &q); + p += q; + p += print_backtrace(tmp + p); + tmp[p] = '\n'; + tmp[p + 1] = 0; + } else { + sprintf(tmp + nesting_level, + "bl to %8x (from %8x)\n", cpu->reg[15], cpu->reg[14]); + } + + logmsg(LOG_TRACE, 10, tmp); + log_inc_indent(); + } else + logmsg(LOG_TRACE, 10, "bl to %8x (from %8x)\n", cpu->reg[15], cpu->reg[14]); +} + +static void function_entry(struct cpu *cpu, struct function *f) { + int i, p, q, logon; + char tmp[200]; + + logon = !quiet && log_check(LOG_TRACE, 5); + if (logon) { + sprintf(tmp, "function %s(%n", f->name, &p); + for (i = 0; i < f->n_args; i++) { + uint32 val; + + if (i < 4) + val = cpu->reg[i]; + else + val = memory_read_word(cpu->mem, cpu->reg[13] + (i - 4) * 4, NULL, 0); + + if (i > 0) { + strcpy(tmp + p, ", "); + p += 2; + } + sprintf(tmp + p, "0x%x%n", val, &q); + p += q; + } + } + + if (f->action == 1) { + if (logon) + sprintf(tmp + p, ") (ignored)\n"); + cpu->reg[15] = cpu->reg[14]; + } else if (f->action == 2) { + if (logon) + sprintf(tmp + p, ") (folded)\n"); + quiet = 1; + } else + if (logon) + sprintf(tmp + p, ")\n"); + if (logon) + logmsg(LOG_TRACE, 5, tmp); +} + +void trace(struct cpu *cpu) { + int i; + + /* + if (cpu->reg[15] >= 0x83e5e8 && cpu->reg[15] <= 0x83e69c) { + logmsg(LOG_TRACE, 5, "in div64: cpsr=%8x\n", cpu->cpsr); + for (i = 0; i < 4; i++) + logmsg(LOG_TRACE, 5, "r%02d=%8x r%02d=%8x r%02d=%8x r%02d=%8x\n", + i * 4, cpu->reg[i * 4], i * 4 + 1, cpu->reg[i * 4 + 1], + i * 4 + 2, cpu->reg[i * 4 + 2], i * 4 + 3, cpu->reg[i * 4 + 3]); + } + */ + + /* + if (cpu->reg[15] == 0x40da24 || cpu->reg[15] == 0x40e0b8) { + uint32 start, n; + static uint32 a, n1; + if (cpu->reg[15] == 0x40da24) { + start = a = cpu->reg[1]; + n = n1 = cpu->reg[0]; + }else { + start = a; + n = n1; + } + + logmsg(LOG_TRACE, 5, "mdct %s:\n", cpu->reg[15] == 0x40da24 ? "in" : "out"); + for (i = 0; i < n; i += 8) + logmsg(LOG_TRACE, 5, "m: %8x %8x %8x %8x %8x %8x %8x %8x\n", + memory_read_word(cpu->mem, start + i + 0), + memory_read_word(cpu->mem, start + i + 4), + memory_read_word(cpu->mem, start + i + 8), + memory_read_word(cpu->mem, start + i + 12), + memory_read_word(cpu->mem, start + i + 16), + memory_read_word(cpu->mem, start + i + 20), + memory_read_word(cpu->mem, start + i + 24), + memory_read_word(cpu->mem, start + i + 28)); + } + */ + + if (cpu->reg[14] == last_pc + 4) + trace_bl(cpu, 1); + last_pc = cpu->reg[15]; + + int a, b; + if (last_pc + 4 == cpu->reg[15]) { + a = last_func; + b = last_func + 2; + if (b > n_functions) b = n_functions; + } else { + a = 0; + b = n_functions; + } + while (b - a > 1) { + int m = (a + b) / 2; + if (functions[m].adr <= cpu->reg[15]) + a = m; + else + b = m; + } + last_func = a; + if (functions[a].adr == cpu->reg[15]) + function_entry(cpu, functions + a); + + if (stack_tracing) { + while (nesting_level > 0 + && link_stack[nesting_level - 1] == cpu->reg[15]) { + quiet = 0; + nesting_level--; + log_dec_indent(); + } + } +} Index: utils/emuriver/src/usb.h =================================================================== --- utils/emuriver/src/usb.h (revision 0) +++ utils/emuriver/src/usb.h (revision 0) @@ -0,0 +1,79 @@ +/* iRiver iFP 7XX Emulator + Copyright (C) 2005 Tomasz Malesinski + + 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 */ + +#ifndef _USB_H_ +#define _USB_H_ + +#include "emuriver.h" + +#define USB_ERR_ENDPOINT_DISABLED -1 +#define USB_ERR_BUFFER_FULL -2 + +#define USB_BUF_SIZE 1024 + +struct usb_in_fifo { + int ptr; + int len; + uint8 data[USB_BUF_SIZE]; +}; + +struct usb_endpoint { + uint32 buflen; + uint8 ctrl; + uint32 maxpacketsize; + uint32 type; + struct usb_in_fifo in_fifo; + + uint8 out_buf[USB_BUF_SIZE]; + int out_ptr; +}; + +struct usb { + struct usb_endpoint endpoint[16]; + uint32 mode_reg; + uint32 inten_reg; + uint32 int_status; + uint8 intconf_reg; + uint8 index_reg; + + struct usb_in_fifo setup_in_fifo; + + uint8 in_buf[USB_BUF_SIZE]; + int in_buf_ptr; +}; + +struct usb *create_usb(void); +void free_usb(struct usb *usb); + +void usb_reset(struct usb *usb); + +uint8 usb_read(void *data, uint32 adr); +void usb_write(void *data, uint32 adr, uint8 val); +uint32 usb_read_half_word(void *data, uint32 adr); +void usb_write_half_word(void *data, uint32 adr, uint32 val); +uint32 usb_read_word(void *data, uint32 adr); +void usb_write_word(void *data, uint32 adr, uint32 val); + +void usb_receive_byte(struct usb *usb, uint8 byte); +int usb_rcv_setup(struct usb *usb); +int usb_rcv_data(struct usb *usb, int e); +int usb_bus_reset(struct usb *usb); +int usb_suspend(struct usb *usb); +int usb_resume(struct usb *usb); +int usb_hs_stat(struct usb *usb); + +#endif Index: utils/emuriver/src/profile.c =================================================================== --- utils/emuriver/src/profile.c (revision 0) +++ utils/emuriver/src/profile.c (revision 0) @@ -0,0 +1,102 @@ +/* iRiver iFP 7XX Emulator + Copyright (C) 2006 Tomasz Malesinski + + 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 */ + +#include +#include "profile.h" + +static char *counter_name[PROFILE_NUM_COUNTERS] = { + "CPUC", "IRMA", "SRMA", "CMIS", "CHIT", "CFLU" +}; + +struct profile *create_profile(void) { + struct profile *profile; + int i; + + profile = xmalloc(sizeof(struct profile)); + if (!profile) return NULL; + + for (i = 0; i < 1 << 16; i++) + profile->region[i] = 0; + + return profile; +} + +static struct profile_region *get_region(struct profile *profile, + int region) { + if (!profile->region[region]) { + profile->region[region] = xmalloc(sizeof(struct profile_region)); + if (profile->region[region]) { + int i; + for (i = 0; i < PROFILE_NUM_COUNTERS; i++) + profile->region[region]->counter[i] = NULL; + } + } + return profile->region[region]; +} + +static int create_counter(struct profile_region *profile_region, + int counter) { + if (profile_region->counter[counter]) + return 0; + profile_region->counter[counter] = xmalloc(sizeof(int) * (1 << 16)); + if (profile_region->counter[counter]) { + memset(profile_region->counter[counter], 0, sizeof(int) * (1 << 16)); + return 0; + } else + return -1; +} + +int profile_add_counter(struct profile *profile, int counter, + uint32 start, uint32 end) { + int i; + for (i = start >> 16; i <= end >> 16; i++) { + struct profile_region *region = get_region(profile, i); + if (!region) return -1; + if (create_counter(region, counter) < 0) + return -1; + } + return 0; +} + +void profile_count(struct profile *profile, uint32 addr, + int counter, int value) { + if (profile) { + struct profile_region *region = profile->region[addr >> 16]; + if (region && region->counter[counter]) + region->counter[counter][addr & ((1 << 16) - 1)] += value; + } +} + +void profile_dump(struct profile *profile, FILE *fp) { + int r, c, i; + for (r = 0; r < 1 << 16; r++) + if (profile->region[r]) + for (i = 0; i < 1 << 16; i++) { + int non_zero = 0; + for (c = 0; c < PROFILE_NUM_COUNTERS && !non_zero; c++) + if (profile->region[r]->counter[c] && + profile->region[r]->counter[c][i]) + non_zero = 1; + if (!non_zero) continue; + fprintf(fp, "%08x:", (r << 16) + i); + for (c = 0; c < PROFILE_NUM_COUNTERS; c++) + if (profile->region[r]->counter[c]) + fprintf(fp, " %s=%9d", counter_name[c], + profile->region[r]->counter[c][i]); + fprintf(fp, "\n"); + } +} Index: utils/emuriver/src/gdb.h =================================================================== --- utils/emuriver/src/gdb.h (revision 0) +++ utils/emuriver/src/gdb.h (revision 0) @@ -0,0 +1,23 @@ +/* iRiver iFP 7XX Emulator + Copyright (C) 2005 Tomasz Malesinski + + 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 */ + +#ifndef _GDB_H_ +#define _GDB_H_ + +void gdb_target(void); + +#endif Index: utils/emuriver/src/Makefile.in =================================================================== --- utils/emuriver/src/Makefile.in (revision 0) +++ utils/emuriver/src/Makefile.in (revision 0) @@ -0,0 +1,395 @@ +# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999, 2001 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. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +CC = @CC@ +CURSES_LIB = @CURSES_LIB@ +HAVE_LIB = @HAVE_LIB@ +LIB = @LIB@ +LTLIB = @LTLIB@ +MAKEINFO = @MAKEINFO@ +PACKAGE = @PACKAGE@ +RANLIB = @RANLIB@ +SDL_CFLAGS = @SDL_CFLAGS@ +SDL_CONFIG = @SDL_CONFIG@ +SDL_LIBS = @SDL_LIBS@ +UI_OBJS = @UI_OBJS@ +VERSION = @VERSION@ + +SUBDIRS = common flashimgtool + +bin_PROGRAMS = emuriver make_flash_img +emuriver_SOURCES = main.c cpu.c memory.c trace.c hardware.c log.c gdb.c lcd.c trainer.c event.c usb.c cpu.h emuriver.h event.h gdb.h hardware.h lcd.h log.h memory.h trace.h trainer.h usb.h ui.c ui.h flash.c flash.h profile.c profile.h + + +EXTRA_emuriver_SOURCES = uicurses.c uisdl.c +emuriver_LDADD = @CURSES_LIB@ @SDL_LIBS@ @UI_OBJS@ +emuriver_DEPENDENCIES = @UI_OBJS@ +make_flash_img_SOURCES = make_flash_img.c +mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs +CONFIG_HEADER = ../config.h +CONFIG_CLEAN_FILES = +PROGRAMS = $(bin_PROGRAMS) + + +DEFS = @DEFS@ -I. -I$(srcdir) -I.. +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +emuriver_OBJECTS = main.o cpu.o memory.o trace.o hardware.o log.o gdb.o \ +lcd.o trainer.o event.o usb.o ui.o flash.o profile.o +emuriver_LDFLAGS = +make_flash_img_OBJECTS = make_flash_img.o +make_flash_img_LDADD = $(LDADD) +make_flash_img_DEPENDENCIES = +make_flash_img_LDFLAGS = +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP_ENV = --best +SOURCES = $(emuriver_SOURCES) $(EXTRA_emuriver_SOURCES) $(make_flash_img_SOURCES) +OBJECTS = $(emuriver_OBJECTS) $(make_flash_img_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .o .s +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps src/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-binPROGRAMS: + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) + +distclean-binPROGRAMS: + +maintainer-clean-binPROGRAMS: + +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(bindir) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ + $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + else :; fi; \ + done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + list='$(bin_PROGRAMS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + done + +.c.o: + $(COMPILE) -c $< + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +emuriver: $(emuriver_OBJECTS) $(emuriver_DEPENDENCIES) + @rm -f emuriver + $(LINK) $(emuriver_LDFLAGS) $(emuriver_OBJECTS) $(emuriver_LDADD) $(LIBS) + +make_flash_img: $(make_flash_img_OBJECTS) $(make_flash_img_DEPENDENCIES) + @rm -f make_flash_img + $(LINK) $(make_flash_img_LDFLAGS) $(make_flash_img_OBJECTS) $(make_flash_img_LDADD) $(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. + +@SET_MAKE@ + +all-recursive install-data-recursive install-exec-recursive \ +installdirs-recursive install-recursive uninstall-recursive \ +check-recursive installcheck-recursive info-recursive dvi-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; 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; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ + rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \ + rev="$$subdir $$rev"; \ + test "$$subdir" != "." || dot_seen=yes; \ + done; \ + test "$$dot_seen" = "no" && rev=". $$rev"; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags -o $$here/TAGS $(ETAGS_ARGS) $$tags $$unique $(LISP)) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = src + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + for subdir in $(SUBDIRS); do \ + if test "$$subdir" = .; then :; else \ + test -d $(distdir)/$$subdir \ + || mkdir $(distdir)/$$subdir \ + || exit 1; \ + chmod 777 $(distdir)/$$subdir; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(top_distdir) distdir=../$(distdir)/$$subdir distdir) \ + || exit 1; \ + fi; \ + done +cpu.o: cpu.c emuriver.h cpu.h log.h profile.h +event.o: event.c event.h +flash.o: flash.c flash.h emuriver.h log.h +gdb.o: gdb.c emuriver.h cpu.h hardware.h event.h log.h ui.h lcd.h usb.h +hardware.o: hardware.c memory.h emuriver.h profile.h cpu.h hardware.h \ + event.h log.h lcd.h usb.h flash.h +lcd.o: lcd.c log.h lcd.h emuriver.h +log.o: log.c log.h +main.o: main.c emuriver.h memory.h profile.h cpu.h hardware.h event.h \ + trace.h trainer.h gdb.h ui.h lcd.h flash.h +make_flash_img.o: make_flash_img.c +memory.o: memory.c emuriver.h memory.h profile.h cpu.h log.h +profile.o: profile.c profile.h emuriver.h +trace.o: trace.c trace.h cpu.h emuriver.h memory.h profile.h log.h +trainer.o: trainer.c emuriver.h +ui.o: ui.c ui.h lcd.h emuriver.h ../config.h +uicurses.o: uicurses.c ui.h lcd.h emuriver.h trainer.h +usb.o: usb.c usb.h emuriver.h log.h + +info-am: +info: info-recursive +dvi-am: +dvi: dvi-recursive +check-am: all-am +check: check-recursive +installcheck-am: +installcheck: installcheck-recursive +install-exec-am: install-binPROGRAMS +install-exec: install-exec-recursive + +install-data-am: +install-data: install-data-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-recursive +uninstall-am: uninstall-binPROGRAMS +uninstall: uninstall-recursive +all-am: Makefile $(PROGRAMS) +all-redirect: all-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: installdirs-recursive +installdirs-am: + $(mkinstalldirs) $(DESTDIR)$(bindir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-compile \ + mostlyclean-tags mostlyclean-generic + +mostlyclean: mostlyclean-recursive + +clean-am: clean-binPROGRAMS clean-compile clean-tags clean-generic \ + mostlyclean-am + +clean: clean-recursive + +distclean-am: distclean-binPROGRAMS distclean-compile distclean-tags \ + distclean-generic clean-am + +distclean: distclean-recursive + +maintainer-clean-am: maintainer-clean-binPROGRAMS \ + maintainer-clean-compile maintainer-clean-tags \ + maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-recursive + +.PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \ +maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \ +mostlyclean-compile distclean-compile clean-compile \ +maintainer-clean-compile install-data-recursive \ +uninstall-data-recursive install-exec-recursive \ +uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \ +all-recursive check-recursive installcheck-recursive info-recursive \ +dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \ +maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir info-am info \ +dvi-am dvi check check-am installcheck-am installcheck install-exec-am \ +install-exec install-data-am install-data install-am install \ +uninstall-am uninstall all-redirect all-am all installdirs-am \ +installdirs mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +uisdl.o: uisdl.c + $(COMPILE) $(SDL_CFLAGS) -c $(srcdir)/uisdl.c + +# 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: Index: utils/emuriver/src/flash.h =================================================================== --- utils/emuriver/src/flash.h (revision 0) +++ utils/emuriver/src/flash.h (revision 0) @@ -0,0 +1,48 @@ +/* iRiver iFP 7XX Emulator + Copyright (C) 2006 Tomasz Malesinski + + 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 */ + +#ifndef _FLASH_H_ +#define _FLASH_H_ + +#include "emuriver.h" + +#define FLASH_256_8 0 +#define FLASH_512_8 1 +#define FLASH_1024_8 2 + +struct flash { + int model; + uint8 reg[2112]; + int offset; + int page; + int ptr; + int adr_ptr; + int only_oob; + FILE *fp; + + int busy, ready_tick; + + uint8 adr[5]; + uint8 cmd; +}; + +struct flash *create_flash(int model, char *fname, int offset); +void free_flash(struct flash *flash); +uint8 flash_read(struct flash *flash, int adr); +void flash_write(struct flash *flash, int adr, uint8 val); + +#endif Index: utils/emuriver/src/hardware.h =================================================================== --- utils/emuriver/src/hardware.h (revision 0) +++ utils/emuriver/src/hardware.h (revision 0) @@ -0,0 +1,157 @@ +/* iRiver iFP 7XX Emulator + Copyright (C) 2005 Tomasz Malesinski + + 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 */ + +#ifndef _HARDWARE_H_ +#define _HARDWARE_H_ + +#include "emuriver.h" +#include +#include "event.h" + +struct gpio_handler { + void *data; + int (*get)(void *data, int port, int bit); + void (*set)(void *data, int port, int bit, int value); +}; + +struct dma_channel { + uint32 src; + uint32 dest; + uint32 len; + uint32 config; + uint32 enable; + uint32 count; + struct event event; + struct dma_ctrl *dma; + int n; +}; + +struct dma_ctrl { + uint32 intstat; + uint32 inten; + struct dma_channel channel[8]; + struct hardware *hardware; + struct memory *memory; +}; + +#define AUDIO_LEFT 0 +#define AUDIO_RIGHT 1 + +struct audio { + uint32 dacctrl; + uint32 dacset; + uint32 siocr; + FILE *out_file[2]; +}; + +struct clocks { + uint32 base_scr[12]; + uint32 base_fs1[12]; + uint32 base_fs2[12]; + uint32 base_ssr[12]; + uint32 clk_pcr[73]; + uint32 clk_esr[67]; + uint32 base_bcr[3]; + uint32 base_fdc[18]; +}; + +struct mmu_cache_line { + uint8 data[2][32]; + uint32 addr[2]; + unsigned char dirty[2]; + unsigned char lru; +}; + +struct mmu_cache { + struct mmu_cache_line line[128]; + struct mmu_block* block; + uint32 settings; +}; + +struct mmu_block { + int phys_block; + uint32 phys_adr; + struct memory *memory; + struct mmu_cache *cache; + unsigned char cache_enabled; +}; + +struct pnx0101_timer { + uint32 counter; + uint32 reload; + uint32 ctrl; + struct event event; + int active; + int index; + struct hardware *hardware; + unsigned int last_tick; +}; + +struct hardware { + uint32 gpio_dir[8]; + uint32 gpio_out[8]; + struct gpio_handler gpio_handler[8][32]; + + struct flash *flash[4]; + struct prog_flash *prog_flash; + + struct lcd *lcd; + struct usb *usb; + int usb_connected; + + uint32 irq_reg[0x140]; + uint32 irq_request; + + struct dma_ctrl dma_ctrl; + struct audio audio; + struct clocks clocks; + struct pnx0101_timer timer[2]; + + struct memory *phys_memory; + struct memory *memory; + struct mmu_cache cache; + struct mmu_block mmu[16]; + + char log_buf[128]; + int log_ptr; +}; + +struct prog_flash { + int state; + FILE *fp; + uint8 *content; +}; + +extern unsigned int tick; + +int tick_before(unsigned int a, unsigned int b); + +int gpio_get_bit(struct hardware *hardware, int port, int bit); +void gpio_install_handler(struct hardware *hardware, int port, int bit, + void *data, + int (*get)(void *, int, int), + void (*set)(void *, int, int, int)); + +void install_hardware(struct hardware *hardware, struct memory *memory); +void hardware_reset(struct hardware *hardware, struct memory *memory); +struct hardware *create_hardware(void); +void hardware_connect_flash(struct hardware *hardware, + int n, struct flash *flash); + +int check_irq(void *data); + +#endif Index: utils/emuriver/src/trace.h =================================================================== --- utils/emuriver/src/trace.h (revision 0) +++ utils/emuriver/src/trace.h (revision 0) @@ -0,0 +1,39 @@ +/* iRiver iFP 7XX Emulator + Copyright (C) 2005 Tomasz Malesinski + + 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 */ + +#ifndef _TRACE_H_ +#define _TRACE_H_ + +#include "cpu.h" + +void trace(struct cpu *cpu); +void trace_init(void); + +struct function { + uint32 adr; + char *name; + int n_args; + int action; +}; + +extern struct function functions_ifp121[]; +extern struct function functions_ifpums128[]; +extern struct function functions_ifpums129eu[]; + +extern int stack_tracing; + +#endif Index: utils/emuriver/src/emuriver.h =================================================================== --- utils/emuriver/src/emuriver.h (revision 0) +++ utils/emuriver/src/emuriver.h (revision 0) @@ -0,0 +1,60 @@ +/* iRiver iFP 7XX Emulator + Copyright (C) 2005 Tomasz Malesinski + + 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 */ + +#ifndef _EMURIVER_H_ +#define _EMURIVER_H_ + +#include + +typedef unsigned long uint32; +typedef signed long sint32; +typedef unsigned long long uint64; +typedef signed long long sint64; +typedef unsigned char uint8; + +extern struct cpu *cpu; +extern struct hardware *hardware; + +extern char *flash_file; +extern char *prog_flash_file; + +void error(const char *format, ...); +void error_sys(const char *format, ...); +void *xmalloc(size_t size); + +static inline uint32 ror(uint32 v, int n) { + return (v >> n) | (v << (32 - n)); +} + +static inline uint32 asr(uint32 v, int n) { + return (uint32)(((signed int)v) >> n); +} + +static inline uint32 bits(uint32 v, int b, int n) { + return (v >> b) & ((1 << n) - 1); +} + +static inline int sign_extend(uint32 v, int b) { + if (v & (1 << (b - 1))) + return ((int)v) - (1 << b); + else + return v; +} + +void set_profiling(int on); + +#endif Index: utils/emuriver/src/trainer.c =================================================================== --- utils/emuriver/src/trainer.c (revision 0) +++ utils/emuriver/src/trainer.c (revision 0) @@ -0,0 +1,86 @@ +/* iRiver iFP 7XX Emulator + Copyright (C) 2005 Tomasz Malesinski + + 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 */ + +#include "emuriver.h" + +static uint8 memory_snapshot[0x10000]; +static uint8 possible[0x10000]; +static int started; +static uint8 *memory_block; + +void trainer_init(uint8 *memory) { + started = 0; + memory_block = memory; +} + +void trainer_start(void) { + int i; + + for (i = 0; i < 0x10000; i++) { + memory_snapshot[i] = memory_block[i]; + possible[i] = 1; + } + started = 1; +} + +void trainer_value_changed(void) { + int i; + + if (!started) + return; + + for (i = 0; i < 0x10000; i++) { + if (memory_snapshot[i] == memory_block[i]) + possible[i] = 0; + memory_snapshot[i] = memory_block[i]; + } +} + +void trainer_value_not_changed(void) { + int i; + + if (!started) + return; + + for (i = 0; i < 0x10000; i++) { + if (memory_snapshot[i] != memory_block[i]) + possible[i] = 0; + memory_snapshot[i] = memory_block[i]; + } +} + +int trainer_n_possible(void) { + int i, n; + if (!started) + return -1; + + for (i = 0; i < 0x10000; i++) + if (possible[i]) n++; + return n; +} + +int trainer_get_possible(int *p, int p_len) { + int i, n; + + if (!started) + return -1; + + n = 0; + for (i = 0; i < 0x10000 && n < p_len; i++) + if (possible[i]) p[n++] = i; + return n; +} Index: utils/emuriver/src/profile.h =================================================================== --- utils/emuriver/src/profile.h (revision 0) +++ utils/emuriver/src/profile.h (revision 0) @@ -0,0 +1,47 @@ +/* iRiver iFP 7XX Emulator + Copyright (C) 2006 Tomasz Malesinski + + 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 */ + +#ifndef _PROFILE_H_ +#define _PROFILE_H_ + +#include "emuriver.h" + +#define PROFILE_CTR_CPU_CYCLES 0 +#define PROFILE_CTR_IRAM_ACCESSES 1 +#define PROFILE_CTR_SRAM_ACCESSES 2 +#define PROFILE_CTR_CACHE_MISSES 3 +#define PROFILE_CTR_CACHE_HITS 4 +#define PROFILE_CTR_CACHE_FLUSHES 5 + +#define PROFILE_NUM_COUNTERS 6 + +struct profile_region { + int *counter[PROFILE_NUM_COUNTERS]; +}; + +struct profile { + struct profile_region *region[1 << 16]; +}; + +struct profile *create_profile(void); +int profile_add_counter(struct profile *profile, int counter, + uint32 start, uint32 end); +void profile_count(struct profile *profile, uint32 addr, + int counter, int value); +void profile_dump(struct profile *profile, FILE *fp); + +#endif Index: utils/emuriver/src/trainer.h =================================================================== --- utils/emuriver/src/trainer.h (revision 0) +++ utils/emuriver/src/trainer.h (revision 0) @@ -0,0 +1,30 @@ +/* iRiver iFP 7XX Emulator + Copyright (C) 2005 Tomasz Malesinski + + 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 */ + +#include "emuriver.h" + +#ifndef _TRAINER_H_ +#define _TRAINER_H_ + +void trainer_init(uint8 *memory); +void trainer_start(void); +void trainer_value_changed(void); +void trainer_value_not_changed(void); +int trainer_n_possible(void); +int trainer_get_possible(int *p, int p_len); + +#endif Index: utils/emuriver/src/ui.c =================================================================== --- utils/emuriver/src/ui.c (revision 0) +++ utils/emuriver/src/ui.c (revision 0) @@ -0,0 +1,56 @@ +/* iRiver iFP 7XX Emulator + Copyright (C) 2005 Tomasz Malesinski + + 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 */ + +#include "ui.h" +#include "config.h" + +static struct ui *ui; +static int ui_key_overrides[10]; +int ui_init(void) { +#ifdef HAVE_SDL + ui = &uisdl_functions; + if (!(*ui->init)()) + return 0; +#endif + + ui = &uicurses_functions; + if (!(*ui->init)()) + return 0; + + return -1; +} + +void ui_cleanup(void) { + (*ui->cleanup)(); +} + +void ui_refresh(struct lcd *lcd) { + (*ui->refresh)(lcd); +} + +int ui_get_key(int key) { + return (*ui->get_key)(key) || ui_key_overrides[key]; +} + +void ui_set_key_override(int key, int v) { + if (v >= 0 && v < 10) + ui_key_overrides[key] = v; +} + +void ui_set_status(char *s) { + (*ui->set_status)(s); +} Index: utils/emuriver/src/uisdl.c =================================================================== --- utils/emuriver/src/uisdl.c (revision 0) +++ utils/emuriver/src/uisdl.c (revision 0) @@ -0,0 +1,151 @@ +/* iRiver iFP 7XX Emulator + Copyright (C) 2005 Tomasz Malesinski + + 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 */ + +#include "SDL.h" +#include "log.h" +#include "lcd.h" +#include "ui.h" + +static int sdl_after_init = 0; +static SDL_Surface *screen = NULL; +static char key_pressed[10]; + +struct key { + int sdl_key; + int iriver_key; +}; + +static struct key keys[] = { + {SDLK_q, 0}, + {SDLK_1, 1}, + {SDLK_2, 2}, + {SDLK_3, 3}, + {SDLK_SPACE, 4}, + {SDLK_j, 5}, + {SDLK_LEFT, 5}, + {SDLK_l, 6}, + {SDLK_RIGHT, 6}, + {SDLK_i, 7}, + {SDLK_UP, 7}, + {SDLK_k, 8}, + {SDLK_DOWN, 8}, + {-1, -1} +}; + +void sdl_error(char *msg) { + logmsg(LOG_GENERAL, 1, "SDL: %s: ", msg, SDL_GetError()); +} + +static int uisdl_init(void) { + int i; + SDL_Color col[2]; + + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + sdl_error("SDL_Init"); + return -1; + } + sdl_after_init = 1; + + screen = SDL_SetVideoMode(LCD_WIDTH, LCD_HEIGHT, 8, SDL_SWSURFACE); + if (!screen) { + sdl_error("SDL_SetVideoMode"); + return -1; + } + + col[0].r = 128; + col[0].g = 128; + col[0].b = 128; + col[1].r = 10; + col[1].g = 10; + col[1].b = 10; + SDL_SetColors(screen, col, 0, 2); + + for (i = 0; i < 10; i++) + key_pressed[i] = 0; + + return 0; +} + +static void uisdl_cleanup(void) { + if (sdl_after_init) + SDL_Quit(); +} + + +static int key_no(int sym) { + int i; + for (i = 0; keys[i].sdl_key >= 0; i++) + if (sym == keys[i].sdl_key) + return keys[i].iriver_key; + return -1; +} + +static void events_handle(void) { + SDL_Event ev; + int k; + + while (SDL_PollEvent(&ev)) { + switch (ev.type) { + case SDL_QUIT: + key_pressed[0] = 1; + break; + case SDL_KEYDOWN: + k = key_no(ev.key.keysym.sym); + if (k >= 0) + key_pressed[k] = 1; + else if (ev.key.keysym.sym == SDLK_h) + key_pressed[9] = !key_pressed[9]; + break; + case SDL_KEYUP: + k = key_no(ev.key.keysym.sym); + if (k >= 0) + key_pressed[k] = 0; + break; + } + } +} + +static void uisdl_refresh(struct lcd *lcd) { + int i, w, h, x, y; + Uint8 *p; + + SDL_LockSurface(screen); + for (y = 0; y < LCD_HEIGHT; y++) { + p = (Uint8 *)screen->pixels + screen->pitch * y; + for (x = 0; x < LCD_WIDTH; x++) + *p++ = lcd_get_pixel(lcd, x, y) ? 1 : 0; + } + SDL_UnlockSurface(screen); + SDL_UpdateRect(screen, 0, 0, 0, 0); + + events_handle(); +} + +static int uisdl_get_key(int key) { + return key_pressed[key]; +} + +static void uisdl_set_status(char *s) { +} + +struct ui uisdl_functions = { + uisdl_init, + uisdl_cleanup, + uisdl_refresh, + uisdl_get_key, + uisdl_set_status +}; Index: utils/emuriver/src/ui.h =================================================================== --- utils/emuriver/src/ui.h (revision 0) +++ utils/emuriver/src/ui.h (revision 0) @@ -0,0 +1,41 @@ +/* iRiver iFP 7XX Emulator + Copyright (C) 2005 Tomasz Malesinski + + 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 */ + +#ifndef _UI_H_ +#define _UI_H_ + +#include "lcd.h" + +struct ui { + int (*init)(void); + void (*cleanup)(void); + void (*refresh)(struct lcd *); + int (*get_key)(int); + void (*set_status)(char *); +}; + +int ui_init(void); +void ui_cleanup(void); +void ui_refresh(struct lcd *lcd); +int ui_get_key(int key); +void ui_set_key_override(int key, int v); +void ui_set_status(char *s); + +extern struct ui uicurses_functions; +extern struct ui uisdl_functions; + +#endif Index: utils/emuriver/src/cpu.c =================================================================== --- utils/emuriver/src/cpu.c (revision 0) +++ utils/emuriver/src/cpu.c (revision 0) @@ -0,0 +1,1692 @@ +/* iRiver iFP 7XX Emulator + Copyright (C) 2005 Tomasz Malesinski + + 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 */ + +#include +#include + +#include "emuriver.h" +#include "cpu.h" +#include "log.h" +#include "profile.h" + +#define MODE_USER 0x10 +#define MODE_FIQ 0x11 +#define MODE_IRQ 0x12 +#define MODE_SVC 0x13 +#define MODE_ABT 0x17 +#define MODE_UND 0x1b +#define MODE_SYS 0x1f + +typedef void (*instruction)(struct cpu *, uint32); + +static int breaks_find_ge(struct breaks *breaks, uint32 v) { + int a, b; + a = 0; + b = breaks->n; + while (a < b) { + int m = (a + b) / 2; + if (breaks->tab[m] >= v) + b = m; + else + a = m + 1; + } + return a; +} + +static void breaks_delete(struct breaks *breaks, uint32 v) { + int i; + i = breaks_find_ge(breaks, v); + if (i < breaks->n && breaks->tab[i] == v) { + int k; + k = breaks->n - (i + 1); + if (k) + memmove(breaks->tab + i, breaks->tab + i + 1, k * sizeof(uint32)); + breaks->n--; + } +} + +static int breaks_insert(struct breaks *breaks, uint32 v) { + int i, k; + i = breaks_find_ge(breaks, v); + if (i >= breaks->n || breaks->tab[i] != v) { + if (breaks->n == breaks->max_n) + return -1; + + k = breaks->n - i; + if (k) + memmove(breaks->tab + i + 1, breaks->tab + i, k * sizeof(uint32)); + + breaks->tab[i] = v; + breaks->n++; + } + return 0; +} + +static int breaks_overlaps(struct breaks *breaks, uint32 a, uint32 b) { + int i; + i = breaks_find_ge(breaks, a); + return (i < breaks->n && breaks->tab[i] <= b); +} + +static int breaks_init(struct breaks *breaks, int max_n) { + breaks->tab = malloc(sizeof(uint32) * max_n); + if (!breaks->tab) + return -1; + + breaks->n = 0; + breaks->max_n = max_n; + return 0; +} + +static void breaks_cleanup(struct breaks *breaks) { + free(breaks->tab); +} + +static struct breaks *breaks_create(int max_n) { + struct breaks *breaks; + breaks = malloc(sizeof(struct breaks)); + if (!breaks) + return NULL; + + if (breaks_init(breaks, max_n) < 0) { + free(breaks); + return NULL; + } + + return breaks; +} + +static struct breaks *cpu_select_breaks(struct cpu *cpu, int type) { + switch (type) { + case CPU_BRK_BREAK: + return &cpu->breakpoints; + case CPU_BRK_RWATCH: + return &cpu->rwatchpoints; + case CPU_BRK_WWATCH: + return &cpu->wwatchpoints; + case CPU_BRK_AWATCH: + return &cpu->awatchpoints; + default: + return NULL; + } +} + +int cpu_insert_break(struct cpu *cpu, int type, uint32 val) { + struct breaks *breaks = cpu_select_breaks(cpu, type); + if (breaks) + return breaks_insert(breaks, val); + else + return -1; +} + +void cpu_remove_break(struct cpu *cpu, int type, uint32 val) { + struct breaks *breaks = cpu_select_breaks(cpu, type); + if (breaks) + breaks_delete(breaks, val); +} + +static void check_memory_read(struct cpu *cpu, uint32 addr1, uint32 addr2) { + if (breaks_overlaps(&cpu->rwatchpoints, addr1, addr2)) { + cpu->stop = CPU_STOP_RWATCH; + cpu->break_addr = addr1; + } + + if (breaks_overlaps(&cpu->awatchpoints, addr1, addr2)) { + cpu->stop = CPU_STOP_AWATCH; + cpu->break_addr = addr1; + } +} + +static void check_memory_write(struct cpu *cpu, uint32 addr1, uint32 addr2) { + if (breaks_overlaps(&cpu->wwatchpoints, addr1, addr2)) { + cpu->stop = CPU_STOP_WWATCH; + cpu->break_addr = addr1; + } + + if (breaks_overlaps(&cpu->awatchpoints, addr1, addr2)) { + cpu->stop = CPU_STOP_AWATCH; + cpu->break_addr = addr1; + } +} + +static uint8 cpu_memory_read(struct cpu *cpu, uint32 addr) { + check_memory_read(cpu, addr, addr); + return memory_read(cpu->mem, addr, cpu->profile, cpu->reg[15] - 4); +} + +static uint32 cpu_memory_read_half_word(struct cpu *cpu, uint32 addr) { + check_memory_read(cpu, addr, addr + 1); + return memory_read_half_word(cpu->mem, addr, + cpu->profile, cpu->reg[15] - 4); +} + +static uint32 cpu_memory_read_word(struct cpu *cpu, uint32 addr) { + check_memory_read(cpu, addr, addr + 3); + return memory_read_word(cpu->mem, addr, cpu->profile, cpu->reg[15] - 4); +} + +static void cpu_memory_write(struct cpu *cpu, uint32 addr, uint8 val) { + check_memory_write(cpu, addr, addr); + memory_write(cpu->mem, addr, val, cpu->profile, cpu->reg[15] - 4); +} + +static void cpu_memory_write_half_word(struct cpu *cpu, + uint32 addr, uint32 val) { + check_memory_write(cpu, addr, addr + 1); + memory_write_half_word(cpu->mem, addr, val, + cpu->profile, cpu->reg[15] - 4); +} + +static void cpu_memory_write_word(struct cpu *cpu, + uint32 addr, uint32 val) { + check_memory_write(cpu, addr, addr + 3); + memory_write_word(cpu->mem, addr, val, cpu->profile, cpu->reg[15] - 4); +} + +static inline count_cycles(int n) { + profile_count(cpu->profile, cpu->reg[15] - 4, PROFILE_CTR_CPU_CYCLES, n); +} + +static void i_unknown(struct cpu *cpu, uint32 opcode) { + cpu->stop = CPU_STOP_ILLEGAL; + cpu->reg[15] -= 4; +} + +static inline int is_extended(uint32 opcode) { + return (opcode & 0x02000090) == 0x90; +} + +static void set_n(struct cpu *cpu, int val) { + cpu->cpsr = (cpu->cpsr & ~(1 << 31)) | (val << 31); +} + +static void set_z(struct cpu *cpu, int val) { + cpu->cpsr = (cpu->cpsr & ~(1 << 30)) | (val << 30); +} + +static void set_nz(struct cpu *cpu, uint32 val) { + cpu->cpsr = (cpu->cpsr & ~((1 << 31) | (1 << 30))) + | (val & (1 << 31)) + | ((val == 0) << 30); +} + +static void set_c(struct cpu *cpu, int val) { + cpu->cpsr = (cpu->cpsr & ~(1 << 29)) | (val << 29); +} + +static int get_c(struct cpu *cpu) { + return bits(cpu->cpsr, 29, 1); +} + +static void set_v_after_add(struct cpu *cpu, uint32 a, uint32 b, uint32 res) { + int v = ((~a ^ b) & (a ^ res) & (1 << 31)) >> 3; + cpu->cpsr = (cpu->cpsr & ~(1 << 28)) | v; +} + +static void set_v_after_sub(struct cpu * cpu, uint32 a, uint32 b, uint32 res) { + int v = ((a ^ b) & (a ^ res) & (1 << 31)) >> 3; + cpu->cpsr = (cpu->cpsr & ~(1 << 28)) | v; +} + +static uint32 shifter(struct cpu *cpu, uint32 opcode, int set_carry) { + int b = bits(opcode, 20, 8); + if ((b & 0xe0) == 0x20) { + uint32 operand = ror(bits(opcode, 0, 8), bits(opcode, 8, 4) * 2); + if (set_carry && bits(opcode, 8, 4) != 0) + set_c(cpu, bits(operand, 31, 1)); + return operand; + } else if ((b & 0xe0) == 0) { + + if (bits(opcode, 4, 3) == 0) { + int shift_imm = bits(opcode, 7, 5); + int m = bits(opcode, 0, 4); + uint32 rm = cpu->reg[m] + (m == 15 ? 4 : 0); + if (shift_imm == 0) + return rm; + else { + if (set_carry) + set_c(cpu, bits(rm, 32 - shift_imm, 1)); + return rm << shift_imm; + } + + } else if (bits(opcode, 4, 4) == 1) { + int rs = cpu->reg[bits(opcode, 8, 4)] & 0xff; + count_cycles(1); + uint32 rm = cpu->reg[bits(opcode, 0, 4)]; + if (rs == 0) + return rm; + else if (rs < 32) { + if (set_carry) + set_c(cpu, bits(rm, 32 - rs, 1)); + return rm << rs; + } else if (rs == 32) { + if (set_carry) + set_c(cpu, bits(rm, 0, 1)); + return 0; + } else { + if (set_carry) + set_c(cpu, 0); + return 0; + } + + } else if (bits(opcode, 4, 3) == 2) { + int shift_imm = bits(opcode, 7, 5); + int m = bits(opcode, 0, 4); + uint32 rm = cpu->reg[m] + (m == 15 ? 4 : 0); + if (shift_imm == 0) { + if (set_carry) + set_c(cpu, bits(rm, 31, 1)); + return 0; + } else { + if (set_carry) + set_c(cpu, bits(rm, shift_imm - 1, 1)); + return rm >> shift_imm; + } + + } else if (bits(opcode, 4, 4) == 3) { + int rs = cpu->reg[bits(opcode, 8, 4)] & 0xff; + count_cycles(1); + uint32 rm = cpu->reg[bits(opcode, 0, 4)]; + if (rs == 0) + return rm; + else if (rs < 32) { + if (set_carry) + set_c(cpu, bits(rm, rs - 1, 1)); + return rm >> rs; + } else if (rs == 32) { + if (set_carry) + set_c(cpu, bits(rm, 31, 1)); + return 0; + } else { + if (set_carry) + set_c(cpu, 0); + return 0; + } + + } else if (bits(opcode, 4, 3) == 4) { + int shift_imm = bits(opcode, 7, 5); + int m = bits(opcode, 0, 4); + uint32 rm = cpu->reg[m] + (m == 15 ? 4 : 0); + if (shift_imm == 0) { + if (set_carry) + set_c(cpu, bits(rm, 31, 1)); + return bits(rm, 31, 1) ? ~0 : 0; + } else { + if (set_carry) + set_c(cpu, bits(rm, shift_imm - 1, 1)); + return asr(rm, shift_imm); + } + + } else if (bits(opcode, 4, 4) == 5) { + int rs = cpu->reg[bits(opcode, 8, 4)] & 0xff; + count_cycles(1); + uint32 rm = cpu->reg[bits(opcode, 0, 4)]; + if (rs == 0) + return rm; + else if (rs < 32) { + if (set_carry) + set_c(cpu, bits(rm, rs - 1, 1)); + return asr(rm, rs); + } else if (rs >= 32) { + if (set_carry) + set_c(cpu, bits(rm, 31, 1)); + return bits(rm, 31, 1) ? ~0 : 0; + } + + } else if (bits(opcode, 4, 3) == 6) { + int shift_imm = bits(opcode, 7, 5); + int m = bits(opcode, 0, 4); + uint32 rm = cpu->reg[m] + (m == 15 ? 4 : 0); + if (shift_imm == 0) { + uint32 res = (rm >> 1) | (get_c(cpu) << 31); + if (set_carry) + set_c(cpu, bits(rm, 0, 1)); + return res; + + } else { + if (set_carry) + set_c(cpu, bits(rm, shift_imm - 1, 1)); + return ror(rm, shift_imm); + } + + } else if (bits(opcode, 4, 4) == 7) { + int rs = cpu->reg[bits(opcode, 8, 4)] & 0xff; + count_cycles(1); + uint32 rm = cpu->reg[bits(opcode, 0, 4)]; + if (rs == 0) + return rm; + else if ((rs & 0xf) == 0) { + if (set_carry) + set_c(cpu, bits(rm, 31, 1)); + return rm; + } else { + int rs4 = rs & 0xf; + if (set_carry) + set_c(cpu, bits(rm, rs4 - 1, 1)); + return ror(rm, rs4); + } + + } else { + fprintf(stderr, "Unknown shift %x at %x\n", opcode, + cpu->reg[15] - 4); + } + } else { + fprintf(stderr, "Unknown addressing mode %x at %x\n", opcode, + cpu->reg[15] - 4); + exit(1); + } +} + +static uint32 scaled_register_offset(struct cpu *cpu, uint32 opcode) { + uint32 rm = cpu->reg[bits(opcode, 0, 4)]; + int shift_imm = bits(opcode, 7, 5); + + switch (bits(opcode, 5, 2)) { + case 0: + return rm << shift_imm; + case 1: + if (shift_imm == 0) + return 0; + else + return rm >> shift_imm; + break; + case 2: + if (shift_imm == 0) + if (rm & (1 << 31)) + return ~0; + else + return 0; + else + return asr(rm, shift_imm); + break; + case 3: + if (shift_imm == 0) + return get_c(cpu) << 31 | (rm >> 1); + else + return ror(rm, shift_imm); + break; + } +} + +static uint32 adrmode_2(struct cpu *cpu, uint32 opcode) { + int b = bits(opcode, 20, 8); + int n = bits(opcode, 16, 4); + int rn; + + rn = cpu->reg[n]; + if (n == 15) + rn += 4; + + if ((b & 0xfa) == 0x58) { + /* immediate offset + */ + return rn + bits(opcode, 0, 12); + + } else if ((b & 0xfa) == 0x50) { + /* immediate offset - */ + return rn - bits(opcode, 0, 12); + + } else if ((b & 0xf2) == 0x70) { + /* scaled register offset */ + uint32 rm = cpu->reg[bits(opcode, 0, 4)]; + int shift_imm = bits(opcode, 7, 5); + uint32 index = scaled_register_offset(cpu, opcode); + + if (opcode & (1 << 23)) + return rn + index; + else + return rn - index; + + } else if ((b & 0xf2) == 0x72) { + /* scaled register pre-indexed */ + uint32 rm = cpu->reg[bits(opcode, 0, 4)]; + int shift_imm = bits(opcode, 7, 5); + uint32 index = scaled_register_offset(cpu, opcode); + + if (opcode & (1 << 23)) + return cpu->reg[n] = rn + index; + else + return cpu->reg[n] = rn - index; + + } else if ((b & 0xf2) == 0x60) { + /* scaled register post-indexed */ + uint32 rm = cpu->reg[bits(opcode, 0, 4)]; + int shift_imm = bits(opcode, 7, 5); + uint32 index = scaled_register_offset(cpu, opcode); + + if (opcode & (1 << 23)) + cpu->reg[n] = rn + index; + else + cpu->reg[n] = rn - index; + + return rn; + + } else if ((b & 0xfa) == 0x48) { + /* immediate post-indexed + */ + cpu->reg[n] = rn + bits(opcode, 0, 12); + return rn; + + } else if ((b & 0xfa) == 0x40) { + /* immediate post-indexed - */ + cpu->reg[n] = rn - bits(opcode, 0, 12); + return rn; + + } else if ((b & 0xfa) == 0x5a) { + /* immediate pre-indexed + */ + return cpu->reg[n] = rn + bits(opcode, 0, 12); + + } else if ((b & 0xfa) == 0x52) { + /* immediate pre-indexed - */ + return cpu->reg[n] = rn - bits(opcode, 0, 12); + + } else { + fprintf(stderr, "Unknown addressing mode %x at %x\n", opcode, + cpu->reg[15] - 4); + exit(1); + } +} + +static uint32 adrmode_3(struct cpu *cpu, uint32 opcode) { + int b = bits(opcode, 20, 8); + int n = bits(opcode, 16, 4); + int rn; + + rn = cpu->reg[n]; + if (n == 15) + rn += 4; + + if ((b & 0xfe) == 0x1c) { + /* immediate offset + */ + return rn + bits(opcode, 0, 4) + (bits(opcode, 8, 4) << 4); + } else if ((b & 0xfe) == 0x14) { + /* immediate offset - */ + return rn - bits(opcode, 0, 4) - (bits(opcode, 8, 4) << 4); + } else if ((b & 0xfe) == 0x18) { + /* register offset + */ + return rn + cpu->reg[bits(opcode, 0, 4)]; + } else if ((b & 0xfe) == 0x10) { + /* register offset - */ + return rn - cpu->reg[bits(opcode, 0, 4)]; + + } else if ((b & 0xfe) == 0x0c) { + /* immediate post-indexed + */ + cpu->reg[n] += bits(opcode, 0, 4) + (bits(opcode, 8, 4) << 4); + return rn; + } else if ((b & 0xfe) == 0x04) { + /* immediate post-indexed - */ + cpu->reg[n] -= bits(opcode, 0, 4) + (bits(opcode, 8, 4) << 4); + return rn; + } else if ((b & 0xfe) == 0x08) { + /* register post-indexed + */ + cpu->reg[n] += cpu->reg[bits(opcode, 0, 4)]; + return rn; + } else if ((b & 0xfe) == 0x00) { + /* register post-indexed - */ + cpu->reg[n] -= cpu->reg[bits(opcode, 0, 4)]; + return rn; + + } else if ((b & 0xfe) == 0x1e) { + /* immediate pre-indexed + */ + cpu->reg[n] += bits(opcode, 0, 4) + (bits(opcode, 8, 4) << 4); + return rn; + } else if ((b & 0xfe) == 0x16) { + /* immediate pre-indexed - */ + cpu->reg[n] -= bits(opcode, 0, 4) + (bits(opcode, 8, 4) << 4); + return rn; + } else if ((b & 0xfe) == 0x1a) { + /* register pre-indexed + */ + cpu->reg[n] += cpu->reg[bits(opcode, 0, 4)]; + return rn; + } else if ((b & 0xfe) == 0x12) { + /* register pre-indexed - */ + cpu->reg[n] -= cpu->reg[bits(opcode, 0, 4)]; + return rn; + + } else { + fprintf(stderr, "Unknown addressing mode %x at %x\n", opcode, + cpu->reg[15] - 4); + exit(1); + } +} + + +static void i_ldr(struct cpu *cpu, uint32 opcode) { + uint32 adr = adrmode_2(cpu, opcode); + uint32 val = ror(cpu_memory_read_word(cpu, adr), adr & 3); + int d = bits(opcode, 12, 4); + if (d == 15) { + count_cycles(5); + cpu->reg[15] = val & ~3; + } else { + count_cycles(3); + cpu->reg[d] = val; + } +} + +static void i_ldrb(struct cpu *cpu, uint32 opcode) { + uint32 adr; + uint8 val; + + if ((opcode & 0x0e000010) == 0x06000010) { + i_unknown(cpu, opcode); + return; + } + + adr = adrmode_2(cpu, opcode); + val = cpu_memory_read(cpu, adr); + int d = bits(opcode, 12, 4); + count_cycles(3); + cpu->reg[d] = val; +} + +static inline void uint32_swap(uint32 *a, uint32 *b) { + int t = *a; + *a = *b; + *b = t; +} + +static void array_swap(uint32 *a, uint32 *b, int n) { + int i; + for (i = 0; i < n; i++) + uint32_swap(a + i, b + i); +} + +static void swap_regs(struct cpu *cpu, int mode) { + int i; + + switch (mode) { + case MODE_SVC: + array_swap(cpu->reg + 13, cpu->saved_svc, 2); + uint32_swap(&cpu->spsr, cpu->saved_svc + 2); + break; + + case MODE_ABT: + array_swap(cpu->reg + 13, cpu->saved_abt, 2); + uint32_swap(&cpu->spsr, cpu->saved_abt + 2); + break; + + case MODE_UND: + array_swap(cpu->reg + 13, cpu->saved_und, 2); + uint32_swap(&cpu->spsr, cpu->saved_und + 2); + break; + + case MODE_IRQ: + array_swap(cpu->reg + 13, cpu->saved_irq, 2); + uint32_swap(&cpu->spsr, cpu->saved_irq + 2); + break; + + case MODE_FIQ: + array_swap(cpu->reg + 8, cpu->saved_fiq, 7); + uint32_swap(&cpu->spsr, cpu->saved_fiq + 7); + break; + } +} + +static inline set_cpsr(struct cpu *cpu, uint32 val) { + swap_regs(cpu, cpu->cpsr & 0x1f); + swap_regs(cpu, val & 0x1f); + cpu->cpsr = val; +} + +static void i_ldm1(struct cpu *cpu, uint32 opcode) { + int n = bits(opcode, 16, 4); + int id = bits(opcode, 23, 1); + int ba = bits(opcode, 24, 1); + uint32 adr = cpu->reg[n]; + int i, c; + + c = 0; + for (i = 0; i < 15; i++) + if (opcode & (1 << i)) + c++; + if (opcode & (1 << 15)) + c += 3; + count_cycles(c + 2); + + if (id) { + if (ba) adr += 4; + for (i = 0; i < 16; i++) + if (opcode & (1 << i)) { + cpu->reg[i] = cpu_memory_read_word(cpu, adr); + adr += 4; + } + if (ba) adr -= 4; + } else { + if (ba) adr -= 4; + for (i = 15; i >= 0; i--) + if (opcode & (1 << i)) { + cpu->reg[i] = cpu_memory_read_word(cpu, adr); + adr -= 4; + } + if (ba) adr += 4; + } + + if (opcode & (1 << 15)) + cpu->reg[15] &= ~3; + + if (opcode & (1 << 21)) + cpu->reg[n] = adr; +} + +static void i_ldm3(struct cpu *cpu, uint32 opcode) { + i_ldm1(cpu, opcode); + set_cpsr(cpu, cpu->spsr); +} + +static void i_ldm2_3(struct cpu *cpu, uint32 opcode) { + int n = bits(opcode, 16, 4); + int id = bits(opcode, 23, 1); + int ba = bits(opcode, 24, 1); + uint32 adr = cpu->reg[n]; + int i, c; + + if (bits(opcode, 15, 1)) { + i_ldm3(cpu, opcode); + return; + } + + c = 0; + for (i = 0; i < 15; i++) + if (opcode & (1 << i)) + c++; + if (opcode & (1 << 15)) + c += 3; + count_cycles(c + 2); + + swap_regs(cpu, cpu->cpsr & 0x1f); + if (id) { + if (ba) adr += 4; + for (i = 0; i < 16; i++) + if (opcode & (1 << i)) { + cpu->reg[i] = cpu_memory_read_word(cpu, adr); + adr += 4; + } + if (ba) adr -= 4; + } else { + if (ba) adr -= 4; + for (i = 15; i >= 0; i--) + if (opcode & (1 << i)) { + cpu->reg[i] = cpu_memory_read_word(cpu, adr); + adr -= 4; + } + if (ba) adr += 4; + } + swap_regs(cpu, cpu->cpsr & 0x1f); +} + +static void i_stm1(struct cpu *cpu, uint32 opcode) { + int n = bits(opcode, 16, 4); + int id = bits(opcode, 23, 1); + int ba = bits(opcode, 24, 1); + uint32 adr = cpu->reg[n]; + int i, c; + + c = 0; + if (id) { + if (ba) adr += 4; + for (i = 0; i < 15; i++) + if (opcode & (1 << i)) { + cpu_memory_write_word(cpu, adr, cpu->reg[i]); + adr += 4; + c++; + } + if (ba) adr -= 4; + } else { + if (ba) adr -= 4; + for (i = 15; i >= 0; i--) + if (opcode & (1 << i)) { + cpu_memory_write_word(cpu, adr, cpu->reg[i]); + adr -= 4; + c++; + } + if (ba) adr += 4; + } + count_cycles(c + 1); + + if (opcode & (1 << 21)) + cpu->reg[n] = adr; +} + +static void i_stm2(struct cpu *cpu, uint32 opcode) { + int n = bits(opcode, 16, 4); + int id = bits(opcode, 23, 1); + int ba = bits(opcode, 24, 1); + uint32 adr = cpu->reg[n]; + int i, c; + + c = 0; + swap_regs(cpu, cpu->cpsr & 0x1f); + if (id) { + if (ba) adr += 4; + for (i = 0; i < 15; i++) + if (opcode & (1 << i)) { + cpu_memory_write_word(cpu, adr, cpu->reg[i]); + adr += 4; + c++; + } + if (ba) adr -= 4; + } else { + if (ba) adr -= 4; + for (i = 15; i >= 0; i--) + if (opcode & (1 << i)) { + cpu_memory_write_word(cpu, adr, cpu->reg[i]); + adr -= 4; + c++; + } + if (ba) adr += 4; + } + swap_regs(cpu, cpu->cpsr & 0x1f); + count_cycles(c + 1); +} + +static inline int privileged_mode(struct cpu *cpu) { + return (cpu->cpsr & 0x1f) != MODE_USER; +} + +static inline int mode_has_spsr(struct cpu *cpu) { + return (cpu->cpsr & 0x1f) != MODE_USER + && (cpu->cpsr & 0x1f) != MODE_SYS; +} + +void cpu_set_irq_p(struct cpu *cpu, int (*irq_p)(void *), + void *irq_data) { + cpu->irq_p = irq_p; + cpu->irq_data = irq_data; +} + +void cpu_irq(struct cpu *cpu) { + swap_regs(cpu, cpu->cpsr & 0x1f); + swap_regs(cpu, 0x12); + + cpu->spsr = cpu->cpsr; + cpu->reg[14] = cpu->reg[15] + 4; + cpu->reg[15] = 0x18; + cpu->cpsr = (cpu->cpsr & ~0xbf) | 0x92; +} + +static void i_str(struct cpu *cpu, uint32 opcode) { + /* TODO what if rd=15? */ + uint32 adr = adrmode_2(cpu, opcode); + cpu_memory_write_word(cpu, adr, cpu->reg[bits(opcode, 12, 4)]); + count_cycles(2); +} + +static void i_strb(struct cpu *cpu, uint32 opcode) { + uint32 adr = adrmode_2(cpu, opcode); + cpu_memory_write(cpu, adr, cpu->reg[bits(opcode, 12, 4)] & 0xff); + count_cycles(2); +} + +static mul_cycles(uint32 rs) { + if (!bits(rs, 31, 8)) + return 1; + else if (!bits(rs, 31, 16)) + return 2; + else if (!bits(rs, 31, 24)) + return 3; + else + return 4; +} + +static void i_mul(struct cpu *cpu, uint32 opcode) { + uint32 rs = cpu->reg[bits(opcode, 8, 4)]; + uint32 res = cpu->reg[bits(opcode, 0, 4)] * rs; + count_cycles(1 + mul_cycles(rs)); + cpu->reg[bits(opcode, 16, 4)] = res; + if (opcode & (1 << 20)) + set_nz(cpu, res); +} + +static void i_mla(struct cpu *cpu, uint32 opcode) { + uint32 rs = cpu->reg[bits(opcode, 8, 4)]; + uint32 res = cpu->reg[bits(opcode, 0, 4)] * rs + + cpu->reg[bits(opcode, 12, 4)]; + count_cycles(2 + mul_cycles(rs)); + cpu->reg[bits(opcode, 16, 4)] = res; + if (opcode & (1 << 20)) + set_nz(cpu, res); +} + +static void i_umull(struct cpu *cpu, uint32 opcode) { + uint32 rs = cpu->reg[bits(opcode, 8, 4)]; + uint64 res = (uint64)cpu->reg[bits(opcode, 0, 4)] * rs; + count_cycles(2 + mul_cycles(rs)); + cpu->reg[bits(opcode, 12, 4)] = res & 0xffffffff; + cpu->reg[bits(opcode, 16, 4)] = res >> 32; + if (opcode & (1 << 20)) { + set_n(cpu, (res & (1ULL << 63)) != 0); + set_z(cpu, res == 0); + } +} + +static void i_smull(struct cpu *cpu, uint32 opcode) { + sint32 rs = cpu->reg[bits(opcode, 8, 4)]; + sint64 res = (sint64)((sint32)cpu->reg[bits(opcode, 0, 4)]) * rs; + count_cycles(2 + mul_cycles(rs)); + cpu->reg[bits(opcode, 12, 4)] = res & 0xffffffff; + cpu->reg[bits(opcode, 16, 4)] = res >> 32; + if (opcode & (1 << 20)) { + set_n(cpu, res < 0); + set_z(cpu, res == 0); + } +} + +static void i_umlal(struct cpu *cpu, uint32 opcode) { + int rdl = bits(opcode, 12, 4); + int rdh = bits(opcode, 16, 4); + uint32 rs = cpu->reg[bits(opcode, 8, 4)]; + uint64 res = (uint64)cpu->reg[bits(opcode, 0, 4)] * rs; + + ((uint64)cpu->reg[rdh] << 32) + cpu->reg[rdl]; + count_cycles(3 + mul_cycles(rs)); + cpu->reg[rdl] = res & 0xffffffff; + cpu->reg[rdh] = res >> 32; + if (opcode & (1 << 20)) { + set_n(cpu, (res & (1ULL << 63)) != 0); + set_z(cpu, res == 0); + } +} + +static void i_smlal(struct cpu *cpu, uint32 opcode) { + int rdl = bits(opcode, 12, 4); + int rdh = bits(opcode, 16, 4); + sint32 rs = cpu->reg[bits(opcode, 8, 4)]; + sint64 res = (sint64)((sint32)cpu->reg[bits(opcode, 0, 4)]) * rs + + ((sint64)((sint32)cpu->reg[rdh]) << 32) + cpu->reg[rdl]; + count_cycles(3 + mul_cycles(rs)); + cpu->reg[rdl] = res & 0xffffffff; + cpu->reg[rdh] = res >> 32; + if (opcode & (1 << 20)) { + set_n(cpu, res < 0); + set_z(cpu, res == 0); + } +} + +static void i_strh(struct cpu *cpu, uint32 opcode) { + uint32 data = cpu->reg[bits(opcode, 12, 4)]; + uint32 adr = adrmode_3(cpu, opcode); + count_cycles(2); + cpu_memory_write_half_word(cpu, adr, data & 0xffff); +} + +static void i_ldrh(struct cpu *cpu, uint32 opcode) { + uint32 adr = adrmode_3(cpu, opcode); + uint32 data = cpu_memory_read_half_word(cpu, adr); + count_cycles(3); + cpu->reg[bits(opcode, 12, 4)] = data; +} + +static void i_ldrsh(struct cpu *cpu, uint32 opcode) { + uint32 adr = adrmode_3(cpu, opcode); + uint32 data = cpu_memory_read_half_word(cpu, adr); + count_cycles(3); + cpu->reg[bits(opcode, 12, 4)] = sign_extend(data, 16); +} + +static void i_ldrsb(struct cpu *cpu, uint32 opcode) { + uint32 adr = adrmode_3(cpu, opcode); + uint32 data = cpu_memory_read(cpu, adr); + count_cycles(3); + cpu->reg[bits(opcode, 12, 4)] = sign_extend(data, 8); +} + +static void i_extended(struct cpu *cpu, uint32 opcode) { + switch (opcode & 0x0ff000f0) { + case 0x90: + case 0x00100090: + i_mul(cpu, opcode); + break; + case 0x00200090: + case 0x00300090: + i_mla(cpu, opcode); + break; + case 0x00800090: + case 0x00900090: + i_umull(cpu, opcode); + break; + case 0x00a00090: + case 0x00b00090: + i_umlal(cpu, opcode); + break; + case 0x00c00090: + case 0x00d00090: + i_smull(cpu, opcode); + break; + case 0x00e00090: + case 0x00f00090: + i_smlal(cpu, opcode); + break; + default: + switch (opcode & 0x0e1000f0) { + case 0x000000b0: + i_strh(cpu, opcode); + break; + case 0x001000b0: + i_ldrh(cpu, opcode); + break; + case 0x001000d0: + i_ldrsb(cpu, opcode); + break; + case 0x001000f0: + i_ldrsh(cpu, opcode); + break; + default: + i_unknown(cpu, opcode); + break; + } + } +} + +static void i_adc(struct cpu *cpu, uint32 opcode) { + int s, d, n; + uint32 val, rn; + + if (is_extended(opcode)) { + i_extended(cpu, opcode); + return; + } + + s = bits(opcode, 20, 1); + d = bits(opcode, 12, 4); + val = shifter(cpu, opcode, 0); + n = bits(opcode, 16, 4); + rn = cpu->reg[n]; + if (n == 15) rn += 4; + unsigned long long resl = (unsigned long long)rn + val + get_c(cpu); + uint32 res = resl & 0xffffffff; + int c = (resl >> 32) & 1; + count_cycles((d == 15) ? 3 : 1); + cpu->reg[d] = res; + if (s) { + if (d == 15) + set_cpsr(cpu, cpu->spsr); + else { + set_nz(cpu, res); + set_c(cpu, c); + set_v_after_add(cpu, rn, val, res); + } + } +} + +static void i_add(struct cpu *cpu, uint32 opcode) { + int s, d, n; + uint32 val, rn; + + if (is_extended(opcode)) { + i_extended(cpu, opcode); + return; + } + + s = bits(opcode, 20, 1); + d = bits(opcode, 12, 4); + val = shifter(cpu, opcode, 0); + n = bits(opcode, 16, 4); + rn = cpu->reg[n]; + if (n == 15) rn += 4; + unsigned long long resl = (unsigned long long)rn + val; + uint32 res = resl & 0xffffffff; + int c = (resl >> 32) & 1; + count_cycles((d == 15) ? 3 : 1); + cpu->reg[d] = res; + if (s) { + if (d == 15) + set_cpsr(cpu, cpu->spsr); + else { + set_nz(cpu, res); + set_c(cpu, c); + set_v_after_add(cpu, rn, val, res); + } + } +} + +static void i_and(struct cpu *cpu, uint32 opcode) { + int d, s, n; + uint32 val, rn, res; + + if (is_extended(opcode)) { + i_extended(cpu, opcode); + return; + } + + d = bits(opcode, 12, 4); + s = bits(opcode, 20, 1); + val = shifter(cpu, opcode, s); + n = bits(opcode, 16, 4); + rn = cpu->reg[n]; + if (n == 15) rn += 4; + res = rn & val; + count_cycles((d == 15) ? 3 : 1); + cpu->reg[d] = res; + if (s) + if (d == 15) + set_cpsr(cpu, cpu->spsr); + else + set_nz(cpu, res); +} + +static void i_bic(struct cpu *cpu, uint32 opcode) { + + if (is_extended(opcode)) { + i_extended(cpu, opcode); + return; + } + + int d = bits(opcode, 12, 4); + int s = bits(opcode, 20, 1); + uint32 val = shifter(cpu, opcode, s); + int n = bits(opcode, 16, 4); + uint32 rn = cpu->reg[n]; + if (n == 15) rn += 4; + uint32 res = rn & ~val; + count_cycles((d == 15) ? 3 : 1); + cpu->reg[d] = res; + if (s) + if (d == 15) + set_cpsr(cpu, cpu->spsr); + else + set_nz(cpu, res); +} + +static void i_cmp(struct cpu *cpu, uint32 opcode) { + uint32 val, rn; + int n; + + if (is_extended(opcode)) { + i_extended(cpu, opcode); + return; + } + + val = shifter(cpu, opcode, 0); + n = bits(opcode, 16, 4); + rn = cpu->reg[n]; + if (n == 15) rn += 4; + uint32 res = rn - val; + set_nz(cpu, res); + set_c(cpu, rn >= val); + set_v_after_sub(cpu, rn, val, rn - val); + count_cycles(1); +} + +static void i_cmn(struct cpu *cpu, uint32 opcode) { + uint32 val, rn; + int n; + + if (is_extended(opcode)) { + i_extended(cpu, opcode); + return; + } + + val = shifter(cpu, opcode, 0); + n = bits(opcode, 16, 4); + rn = cpu->reg[n]; + if (n == 15) rn += 4; + + unsigned long long resl = (unsigned long long)rn + val; + uint32 res = resl & 0xffffffff; + + set_nz(cpu, res); + set_c(cpu, (resl >> 32) & 1); + set_v_after_add(cpu, rn, val, res); + count_cycles(1); +} + +static void i_eor(struct cpu *cpu, uint32 opcode) { + int d, s, n; + uint32 val, rn, res; + + if (is_extended(opcode)) { + i_extended(cpu, opcode); + return; + } + + d = bits(opcode, 12, 4); + s = bits(opcode, 20, 1); + val = shifter(cpu, opcode, s); + n = bits(opcode, 16, 4); + rn = cpu->reg[n]; + if (n == 15) rn += 4; + res = rn ^ val; + count_cycles((d == 15) ? 3 : 1); + cpu->reg[d] = res; + if (s) + if (d == 15) + set_cpsr(cpu, cpu->spsr); + else + set_nz(cpu, res); +} + +static void i_mov(struct cpu *cpu, uint32 opcode) { + int d, s; + uint32 val; + + if (is_extended(opcode)) { + i_extended(cpu, opcode); + return; + } + + d = bits(opcode, 12, 4); + s = bits(opcode, 20, 1); + val = shifter(cpu, opcode, s); + count_cycles((d == 15) ? 3 : 1); + cpu->reg[d] = val; + if (s) + if (d == 15) + set_cpsr(cpu, cpu->spsr); + else + set_nz(cpu, val); +} + +static void i_mvn(struct cpu *cpu, uint32 opcode) { + int d, s; + uint32 val; + + if (is_extended(opcode)) { + i_extended(cpu, opcode); + return; + } + + d = bits(opcode, 12, 4); + s = bits(opcode, 20, 1); + val = ~shifter(cpu, opcode, s); + count_cycles((d == 15) ? 3 : 1); + cpu->reg[d] = val; + if (s) + if (d == 15) + set_cpsr(cpu, cpu->spsr); + else + set_nz(cpu, val); +} + +static void i_orr(struct cpu *cpu, uint32 opcode) { + int d, s, n; + uint32 val, rn; + + if (is_extended(opcode)) { + i_extended(cpu, opcode); + return; + } + + d = bits(opcode, 12, 4); + s = bits(opcode, 20, 1); + val = shifter(cpu, opcode, s); + n = bits(opcode, 16, 4); + rn = cpu->reg[n]; + if (n == 15) rn += 4; + uint32 res = rn | val; + count_cycles((d == 15) ? 3 : 1); + cpu->reg[d] = res; + if (s) + if (d == 15) + set_cpsr(cpu, cpu->spsr); + else + set_nz(cpu, res); +} + +static void i_rsb(struct cpu *cpu, uint32 opcode) { + int s, d, n; + uint32 val, rn; + + if (is_extended(opcode)) { + i_extended(cpu, opcode); + return; + } + + s = bits(opcode, 20, 1); + d = bits(opcode, 12, 4); + val = shifter(cpu, opcode, 0); + n = bits(opcode, 16, 4); + rn = cpu->reg[n]; + if (n == 15) rn += 4; + unsigned long long resl = (unsigned long long)val - rn; + uint32 res = resl & 0xffffffff; + int c = ~(resl >> 32) & 1; + count_cycles((d == 15) ? 3 : 1); + cpu->reg[d] = res; + if (s) { + if (d == 15) + set_cpsr(cpu, cpu->spsr); + else { + set_nz(cpu, res); + set_c(cpu, c); + set_v_after_sub(cpu, val, rn, res); + } + } +} + +static void i_rsc(struct cpu *cpu, uint32 opcode) { + int s, d, n; + uint32 val, rn; + + if (is_extended(opcode)) { + i_extended(cpu, opcode); + return; + } + + s = bits(opcode, 20, 1); + d = bits(opcode, 12, 4); + val = shifter(cpu, opcode, 0); + n = bits(opcode, 16, 4); + rn = cpu->reg[n]; + if (n == 15) rn += 4; + unsigned long long resl = (unsigned long long)val - rn + get_c(cpu) - 1; + uint32 res = resl & 0xffffffff; + int c = ~(resl >> 32) & 1; + count_cycles((d == 15) ? 3 : 1); + cpu->reg[d] = res; + if (s) { + if (d == 15) + set_cpsr(cpu, cpu->spsr); + else { + set_nz(cpu, res); + set_c(cpu, c); + set_v_after_sub(cpu, val, rn, res); + } + } +} + +static void i_sbc(struct cpu *cpu, uint32 opcode) { + int s, d, n; + uint32 val, rn; + + if (is_extended(opcode)) { + i_extended(cpu, opcode); + return; + } + + s = bits(opcode, 20, 1); + d = bits(opcode, 12, 4); + val = shifter(cpu, opcode, 0); + n = bits(opcode, 16, 4); + rn = cpu->reg[n]; + if (n == 15) rn += 4; + unsigned long long resl = (unsigned long long)rn - val + get_c(cpu) - 1; + uint32 res = resl & 0xffffffff; + int c = ~(resl >> 32) & 1; + count_cycles((d == 15) ? 3 : 1); + cpu->reg[d] = res; + if (s) { + if (d == 15) + set_cpsr(cpu, cpu->spsr); + else { + set_nz(cpu, res); + set_c(cpu, c); + set_v_after_sub(cpu, rn, val, res); + } + } +} + +static void i_sub(struct cpu *cpu, uint32 opcode) { + int s, d, n; + uint32 val, rn; + + if (is_extended(opcode)) { + i_extended(cpu, opcode); + return; + } + + s = bits(opcode, 20, 1); + d = bits(opcode, 12, 4); + val = shifter(cpu, opcode, 0); + n = bits(opcode, 16, 4); + rn = cpu->reg[n]; + if (n == 15) rn += 4; + unsigned long long resl = (unsigned long long)rn - val; + uint32 res = resl & 0xffffffff; + int c = ~(resl >> 32) & 1; + count_cycles((d == 15) ? 3 : 1); + cpu->reg[d] = res; + if (s) { + if (d == 15) + set_cpsr(cpu, cpu->spsr); + else { + set_nz(cpu, res); + set_c(cpu, c); + set_v_after_sub(cpu, rn, val, res); + } + } +} + +static void i_teq(struct cpu *cpu, uint32 opcode) { + int n; + uint32 val, rn; + + if (is_extended(opcode)) { + i_extended(cpu, opcode); + return; + } + + val = shifter(cpu, opcode, 1); + n = bits(opcode, 16, 4); + rn = cpu->reg[n]; + if (n == 15) rn += 4; + set_nz(cpu, val ^ rn); + count_cycles(1); +} + +static void i_tst(struct cpu *cpu, uint32 opcode) { + int n; + uint32 val, rn; + + if (is_extended(opcode)) { + i_extended(cpu, opcode); + return; + } + + val = shifter(cpu, opcode, 1); + n = bits(opcode, 16, 4); + rn = cpu->reg[n]; + if (n == 15) rn += 4; + set_nz(cpu, val & rn); + count_cycles(1); +} + +static void i_b(struct cpu *cpu, uint32 opcode) { + int offs = sign_extend(bits(opcode, 0, 24), 24) << 2; + count_cycles(3); + cpu->reg[15] += offs + 4; +} + +static void i_bl(struct cpu *cpu, uint32 opcode) { + int offs = sign_extend(bits(opcode, 0, 24), 24) << 2; + count_cycles(3); + cpu->reg[14] = cpu->reg[15]; + cpu->reg[15] += offs + 4; +} + +static void i_mrs(struct cpu *cpu, uint32 opcode) { + int d = bits(opcode, 12, 4); + count_cycles(1); + if (opcode & (1 << 22)) + cpu->reg[d] = cpu->spsr; + else + cpu->reg[d] = cpu->cpsr; +} + +static void i_bx(struct cpu *cpu, uint32 opcode) { + int m = bits(opcode, 0, 4); + count_cycles(3); + cpu->reg[15] = cpu->reg[m]; +} + +static void i_msr(struct cpu *cpu, uint32 opcode) { + uint32 operand; + int i; + + if ((opcode & 0x0ff000f0) == 0x01200010) { + i_bx(cpu, opcode); + return; + } + + count_cycles(1); + if (opcode & (1 << 25)) + operand = ror(bits(opcode, 0, 8), bits(opcode, 8, 4) * 2); + else + operand = cpu->reg[bits(opcode, 0, 4)]; + + if (!(opcode & (1 << 22))) { + if (privileged_mode(cpu)) + for (i = 0; i < 3; i++) + if (opcode & (1 << (16 + i))) { + if (i == 0) { + swap_regs(cpu, cpu->cpsr & 0x1f); + swap_regs(cpu, operand & 0x1f); + } + cpu->cpsr = (cpu->cpsr & ~(0xff << (i * 8))) | (operand & (0xff << (i * 8))); + } + + if (opcode & (1 << 19)) + cpu->cpsr = (cpu->cpsr & ~(0xff << 24)) | (operand & (0xff << 24)); + + } else if (mode_has_spsr(cpu)) + for (i = 0; i < 4; i++) + if (opcode & (1 << (16 + i))) + cpu->spsr = (cpu->cpsr & ~(0xff << (i * 8))) | (operand & (0xff << (i * 8))); +} + +static void i_ctrl(struct cpu *cpu, uint32 opcode) { + if (is_extended(opcode)) + i_extended(cpu, opcode); + else if ((opcode & 0x022000f0) == 0x00000000) + i_mrs(cpu, opcode); + else if ((opcode & 0x022000f0) == 0x00200000) + i_msr(cpu, opcode); + else if ((opcode & 0x026000f0) == 0x00200010) + i_bx(cpu, opcode); + else if ((opcode & 0x02200000) == 0x02200000) + i_msr(cpu, opcode); + else + i_unknown(cpu, opcode); +} + +static instruction instruction_table[256] = { + i_and, i_and, i_eor, i_eor, + i_sub, i_sub, i_rsb, i_rsb, + i_add, i_add, i_adc, i_adc, + i_sbc, i_sbc, i_rsc, i_rsc, + + i_ctrl, i_tst, i_ctrl, i_teq, + i_ctrl, i_cmp, i_ctrl, i_cmn, + i_orr, i_orr, i_mov, i_mov, + i_bic, i_bic, i_mvn, i_mvn, + + i_and, i_and, i_eor, i_eor, + i_sub, i_sub, i_rsb, i_rsb, + i_add, i_add, i_adc, i_adc, + i_sbc, i_sbc, i_rsc, i_rsc, + + i_ctrl, i_tst, i_ctrl, i_teq, + i_ctrl, i_cmp, i_ctrl, i_cmn, + i_orr, i_orr, i_mov, i_mov, + i_bic, i_bic, i_mvn, i_mvn, + + i_str, i_ldr, i_str, i_ldr, + i_strb, i_ldrb, i_strb, i_ldrb, + i_str, i_ldr, i_str, i_ldr, + i_strb, i_ldrb, i_strb, i_ldrb, + + i_str, i_ldr, i_str, i_ldr, + i_strb, i_ldrb, i_strb, i_ldrb, + i_str, i_ldr, i_str, i_ldr, + i_strb, i_ldrb, i_strb, i_ldrb, + + i_str, i_ldr, i_str, i_ldr, + i_strb, i_ldrb, i_strb, i_ldrb, + i_str, i_ldr, i_str, i_ldr, + i_strb, i_ldrb, i_strb, i_ldrb, + + i_str, i_ldr, i_str, i_ldr, + i_strb, i_ldrb, i_strb, i_ldrb, + i_str, i_ldr, i_str, i_ldr, + i_strb, i_ldrb, i_strb, i_ldrb, + + i_stm1, i_ldm1, i_stm1, i_ldm1, + i_stm2, i_ldm2_3, i_unknown, i_unknown, + i_stm1, i_ldm1, i_stm1, i_ldm1, + i_stm2, i_ldm2_3, i_unknown, i_unknown, + + i_stm1, i_ldm1, i_stm1, i_ldm1, + i_stm2, i_ldm2_3, i_unknown, i_unknown, + i_stm1, i_ldm1, i_stm1, i_ldm1, + i_stm2, i_ldm2_3, i_unknown, i_unknown, + + i_b, i_b, i_b, i_b, + i_b, i_b, i_b, i_b, + i_b, i_b, i_b, i_b, + i_b, i_b, i_b, i_b, + + i_bl, i_bl, i_bl, i_bl, + i_bl, i_bl, i_bl, i_bl, + i_bl, i_bl, i_bl, i_bl, + i_bl, i_bl, i_bl, i_bl, + + i_unknown, i_unknown, i_unknown, i_unknown, + i_unknown, i_unknown, i_unknown, i_unknown, + i_unknown, i_unknown, i_unknown, i_unknown, + i_unknown, i_unknown, i_unknown, i_unknown, + + i_unknown, i_unknown, i_unknown, i_unknown, + i_unknown, i_unknown, i_unknown, i_unknown, + i_unknown, i_unknown, i_unknown, i_unknown, + i_unknown, i_unknown, i_unknown, i_unknown, + + i_unknown, i_unknown, i_unknown, i_unknown, + i_unknown, i_unknown, i_unknown, i_unknown, + i_unknown, i_unknown, i_unknown, i_unknown, + i_unknown, i_unknown, i_unknown, i_unknown, + + i_unknown, i_unknown, i_unknown, i_unknown, + i_unknown, i_unknown, i_unknown, i_unknown, + i_unknown, i_unknown, i_unknown, i_unknown, + i_unknown, i_unknown, i_unknown, i_unknown +}; + + +struct cpu *create_cpu(struct memory *memory, struct profile *profile) { + struct cpu *cpu; + + cpu = malloc(sizeof(struct cpu)); + if (!cpu) return NULL; + + if (breaks_init(&cpu->breakpoints, 1024) < 0) + goto nobr; + if (breaks_init(&cpu->rwatchpoints, 1024) < 0) + goto norw; + if (breaks_init(&cpu->wwatchpoints, 1024) < 0) + goto noww; + if (breaks_init(&cpu->awatchpoints, 1024) < 0) + goto noaw; + + cpu->history_ptr = 0; + + cpu->mem = memory; + cpu->cpsr = 0xd3; + cpu->irq_p = NULL; + cpu->profile = profile; + return cpu; + + noaw: + breaks_cleanup(&cpu->wwatchpoints); + noww: + breaks_cleanup(&cpu->rwatchpoints); + norw: + breaks_cleanup(&cpu->breakpoints); + nobr: + free(cpu); + err: + error("error while creating cpu data structures (probably no memory)"); + return NULL; +} + +static inline get_condition(struct cpu *cpu, int cond) { + int b; + switch (cond) { + case 0: /* eq */ + return bits(cpu->cpsr, 30, 1); + case 1: /* ne */ + return !bits(cpu->cpsr, 30, 1); + case 2: /* cs */ + return get_c(cpu); + case 3: /* cc */ + return !get_c(cpu); + case 4: /* mi */ + return bits(cpu->cpsr, 31, 1); + case 5: /* pl */ + return !bits(cpu->cpsr, 31, 1); + case 6: /* vs */ + return bits(cpu->cpsr, 28, 1); + case 7: /* vc */ + return !bits(cpu->cpsr, 28, 1); + case 8: /* hi */ + return (bits(cpu->cpsr, 28, 4) & 6) == 2; + case 9: /* ls */ + return (bits(cpu->cpsr, 28, 4) & 6) != 2; + case 10: /* ge */ + b = bits(cpu->cpsr, 28, 4) & 9; + return b == 9 || b == 0; + case 11: /* lt */ + b = bits(cpu->cpsr, 28, 4) & 9; + return b == 1 || b == 8; + case 12: /* gt */ + b = bits(cpu->cpsr, 28, 4) & 13; + return b == 9 || b == 0; + case 13: /* le */ + b = bits(cpu->cpsr, 28, 4) & 13; + return !(b == 9 || b == 0); + case 14: + return 1; + case 15: + return 0; + } +} + +void cpu_print_registers(struct cpu *cpu, FILE *fp) { + int i; + for (i = 0; i < 16; i++) + fprintf(fp, "r%-2d=%8x%c", i, cpu->reg[i], ((i % 4) == 3) ? '\n' : ' '); +} + +void cpu_execute_instruction(struct cpu *cpu) { + uint32 instr; + static int dbg = 0; + uint32 old_pc; + + if (dbg) + cpu_print_registers(cpu, stderr); + + if (breaks_overlaps(&cpu->breakpoints, + cpu->reg[15], cpu->reg[15] + 3)) { + cpu->stop = CPU_STOP_BREAK; + cpu->break_addr = cpu->reg[15]; + return; + } + + cpu->history[cpu->history_ptr] = cpu->reg[15]; + cpu->history_ptr = (cpu->history_ptr + 1) % CPU_HISTORY_SIZE; + + old_pc = cpu->reg[15]; + cpu->reg[15] += 4; + instr = cpu_memory_read_word(cpu, old_pc); + if (get_condition(cpu, instr >> 28)) + (*(instruction_table[bits(instr, 20, 8)]))(cpu, instr); + else + count_cycles(1); +} + +int cpu_go(struct cpu *cpu, int n_instr) { + cpu->stop = 0; + while (n_instr-- > 0) { + if (!(cpu->cpsr & 0x80) && cpu->irq_p) { + if ((*(cpu->irq_p))(cpu->irq_data)) + cpu_irq(cpu); + } + + trace(cpu); + cpu_execute_instruction(cpu); + if (cpu->stop) + return cpu->stop; + } + return CPU_STOP_NORMAL; +} + +void cpu_history_to_string(struct cpu *cpu, char *buf) +{ + int i, t; + for (i = 0; i < CPU_HISTORY_SIZE; i++) { + sprintf(buf, "%08x %n", + cpu->history[(cpu->history_ptr + i) % CPU_HISTORY_SIZE], + &t); + buf += t; + } +} Index: utils/emuriver/src/cpu.h =================================================================== --- utils/emuriver/src/cpu.h (revision 0) +++ utils/emuriver/src/cpu.h (revision 0) @@ -0,0 +1,80 @@ +/* iRiver iFP 7XX Emulator + Copyright (C) 2005 Tomasz Malesinski + + 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 */ + +#ifndef _CPU_H_ +#define _CPU_H_ + +#include "emuriver.h" + +#define CPU_STOP_NORMAL 1 +#define CPU_STOP_BREAK 2 +#define CPU_STOP_RWATCH 3 +#define CPU_STOP_WWATCH 4 +#define CPU_STOP_AWATCH 5 +#define CPU_STOP_TERMINATE 6 +#define CPU_STOP_QUIT 7 +#define CPU_STOP_ILLEGAL 8 + +#define CPU_HISTORY_SIZE 256 + +struct breaks { + int n, max_n; + uint32 *tab; +}; + +struct cpu { + uint32 reg[16]; + uint32 cpsr; + uint32 spsr; + uint32 saved_svc[3]; + uint32 saved_abt[3]; + uint32 saved_und[3]; + uint32 saved_irq[3]; + uint32 saved_fiq[8]; + struct memory *mem; + struct breaks breakpoints; + struct breaks rwatchpoints; + struct breaks wwatchpoints; + struct breaks awatchpoints; + int stop; + uint32 break_addr; + + int (*irq_p)(void *data); + void *irq_data; + + uint32 history[CPU_HISTORY_SIZE]; + int history_ptr; + + struct profile *profile; +}; + +struct cpu *create_cpu(struct memory *memory, struct profile *profile); +int cpu_go(struct cpu *cpu, int n_instr); +void cpu_set_irq_p(struct cpu *cpu, int (*irq_p)(void *), + void *irq_data); + +#define CPU_BRK_BREAK 1 +#define CPU_BRK_RWATCH 2 +#define CPU_BRK_WWATCH 3 +#define CPU_BRK_AWATCH 4 + +void cpu_remove_break(struct cpu *cpu, int type, uint32 val); +int cpu_insert_break(struct cpu *cpu, int type, uint32 val); + +void cpu_history_to_string(struct cpu *cpu, char *buf); + +#endif Index: utils/emuriver/src/uicurses.c =================================================================== --- utils/emuriver/src/uicurses.c (revision 0) +++ utils/emuriver/src/uicurses.c (revision 0) @@ -0,0 +1,192 @@ +/* iRiver iFP 7XX Emulator + Copyright (C) 2005 Tomasz Malesinski + + 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 */ + +#include +#include + +#include "ui.h" +#include "lcd.h" +#include "trainer.h" + +#define N_KEYS 10 +#define STATUS_LEN 80 + +static int key_timer[10]; +static char status_line[STATUS_LEN + 1]; + +struct key { + int term_key; + int iriver_key; + int time; +}; + +static WINDOW *stdscr_emuriver, *pad; +static pad_x, pad_y; + +#define SHORT 10 +#define LONG 80 + +static struct key keys[] = { + {'q', 0, SHORT}, + {'1', 1, SHORT}, + {'!', 1, LONG}, + {'2', 2, SHORT}, + {'@', 2, LONG}, + {'3', 3, SHORT}, + {'#', 3, LONG}, + {' ', 4, SHORT}, + {'M', 4, LONG}, + {'j', 5, SHORT}, + {'J', 5, LONG}, + {'l', 6, SHORT}, + {'L', 6, LONG}, + {'i', 7, SHORT}, + {'I', 7, LONG}, + {'k', 8, SHORT}, + {'K', 8, LONG}, + {0, 0, 0} +}; + +static void uicurses_set_status(char *s) { + strncpy(status_line, s, STATUS_LEN); + status_line[STATUS_LEN] = 0; +} + +static int uicurses_init(void) { + stdscr_emuriver = initscr(); + cbreak(); + noecho(); + nonl(); + intrflush(stdscr_emuriver, FALSE); + keypad(stdscr_emuriver, TRUE); + nodelay(stdscr_emuriver, 1); + + pad = newpad(LCD_HEIGHT, LCD_WIDTH); + pad_x = pad_y = 0; + + uicurses_set_status(""); + + return 0; +} + +static void uicurses_cleanup(void) { + endwin(); +} + +static void show_trainer_status(void) { + int n = trainer_n_possible(); + char tmp[80]; + + if (n > 3) + sprintf(tmp, "trainer: %d locations possible", n); + else if (n == 0) + sprintf(tmp, "trainer: no possible locations", n); + else { + int p[3]; + int i, j, k; + trainer_get_possible(p, 3); + sprintf(tmp, "trainer: possible:%n", &k); + for (i = 0; i < n; i++) { + sprintf(tmp + k, " %x%n", p[i] + 0x400000, &j); + k += j; + } + } + uicurses_set_status(tmp); +} + +static void keyboard_handle(void) { + int ch, i; + + for (i = 0; i < N_KEYS; i++) + if (key_timer[i]) key_timer[i]--; + + while ((ch = getch()) != ERR) { + switch (ch) { + case KEY_DOWN: + pad_y += 16; + break; + + case KEY_UP: + pad_y -= 16; + if (pad_y < 0) pad_y = 0; + break; + + case KEY_LEFT: + pad_x -= 16; + if (pad_x < 0) pad_x = 0; + break; + + case KEY_RIGHT: + pad_x += 16; + break; + + case 't': + trainer_start(); + show_trainer_status(); + break; + + case 'c': + trainer_value_changed(); + show_trainer_status(); + break; + + case 'C': + trainer_value_not_changed(); + show_trainer_status(); + break; + + default: + for (i = 0; keys[i].term_key; i++) + if (ch == keys[i].term_key) + key_timer[keys[i].iriver_key] = keys[i].time; + break; + } + } +} + +static void uicurses_refresh(struct lcd *lcd) { + int i, w, h, x, y; + + for (y = 0; y < LCD_HEIGHT - 1; y++) + for (x = 0; x < LCD_WIDTH; x++) + mvwaddch(pad, y, x, lcd_get_pixel(lcd, x, y) ? '#' : '.'); + + keyboard_handle(); + getmaxyx(stdscr_emuriver, h, w); + + if (pad_x + w > LCD_WIDTH) + pad_x = LCD_WIDTH - w; + if (pad_y + h > LCD_HEIGHT) + pad_y = LCD_HEIGHT - h; + + prefresh(pad, pad_y, pad_x, 0, 0, h - 2, w - 1); + mvaddstr(h - 1, 0, status_line); + clrtoeol(); + refresh(); +} + +static int uicurses_get_key(int key) { + return key_timer[key] > 0; +} + +struct ui uicurses_functions = { + uicurses_init, + uicurses_cleanup, + uicurses_refresh, + uicurses_get_key, + uicurses_set_status +}; Index: utils/emuriver/src/lcd.c =================================================================== --- utils/emuriver/src/lcd.c (revision 0) +++ utils/emuriver/src/lcd.c (revision 0) @@ -0,0 +1,188 @@ +/* iRiver iFP 7XX Emulator + Copyright (C) 2005 Tomasz Malesinski + + 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 */ + +#include + +#include "log.h" +#include "lcd.h" + +uint32 lcd_read(struct lcd *lcd, uint32 adr) { + int r; + + switch (adr & 0x3f) { + case 8: + logmsg(LOG_LCD, 15, "lcd: status read\n"); + r = 3; + /* + if (!(lcd->flags & LCDFLG_ADC)) + r |= 0x40; + if (!(lcd->flags & LCDFLG_DISPLAY_ON)) + r |= 0x20; + */ + return r; + + default: + logmsg(LOG_LCD, 5, "lcd: read from %x\n", adr); + return ~0; + } +} + +static void lcd_write_control(struct lcd *lcd, uint32 val) { + + if (lcd->flags & LCDFLG_REF_VOLTAGE_SEL) { + logmsg(LOG_LCD, 10, "lcd: reference voltage select %x\n", val & 0x3f); + lcd->flags &= ~LCDFLG_REF_VOLTAGE_SEL; + + } else if (lcd->flags & LCDFLG_SET_STATIC_IND_MODE) { + logmsg(LOG_LCD, 10, "lcd: set static indicator mode %x\n", val & 3); + lcd->flags &= ~LCDFLG_SET_STATIC_IND_MODE; + + } else { + + if ((val & 0xfe) == 0xae) { + logmsg(LOG_LCD, 10, "lcd: display on (%x)\n", val & 1); + if (val & 1) + lcd->flags |= LCDFLG_DISPLAY_ON; + else + lcd->flags &= ~LCDFLG_DISPLAY_ON; + + } else if ((val & 0xc0) == 0x40) { + logmsg(LOG_LCD, 10, "lcd: initial display line %x\n", val & 0x3f); + + } else if (val == 0x81) { + lcd->flags |= LCDFLG_REF_VOLTAGE_SEL; + + } else if ((val & 0xf0) == 0xb0) { + logmsg(LOG_LCD, 10, "lcd: set page address %x\n", val & 0xf); + lcd->page = val & 0xf; + + } else if ((val & 0xf0) == 0x10) { + logmsg(LOG_LCD, 10, "lcd: set column address MSB %x\n", val & 0xf); + lcd->col = (lcd->col & 0xf) | ((val & 0xf) << 4); + + } else if ((val & 0xf0) == 0x00) { + logmsg(LOG_LCD, 10, "lcd: set column address LSB %x\n", val & 0xf); + lcd->col = (lcd->col & 0xf0) | (val & 0xf); + + } else if ((val & 0xfe) == 0xa0) { + logmsg(LOG_LCD, 10, "lcd: set ADC %x\n", val & 1); + if (val & 1) + lcd->flags |= LCDFLG_ADC; + else + lcd->flags &= ~LCDFLG_ADC; + + } else if ((val & 0xfe) == 0xa6) { + logmsg(LOG_LCD, 10, "lcd: reverse display %x\n", val & 1); + + } else if ((val & 0xfe) == 0xa4) { + logmsg(LOG_LCD, 10, "lcd: entire display on %x\n", val & 1); + + } else if ((val & 0xfe) == 0xa2) { + logmsg(LOG_LCD, 10, "lcd: bias %x\n", val & 1); + + } else if (val == 0xe0) { + logmsg(LOG_LCD, 10, "lcd: set modify-read\n"); + + } else if (val == 0xee) { + logmsg(LOG_LCD, 10, "lcd: reset modify-read\n"); + + } else if (val == 0xe2) { + logmsg(LOG_LCD, 10, "lcd: reset\n"); + + } else if ((val & 0xf0) == 0xc0) { + logmsg(LOG_LCD, 10, "lcd: shl select %x\n", (val >> 3) & 1); + + } else if ((val & 0xf8) == 0x28) { + logmsg(LOG_LCD, 10, "lcd: power control %x\n", val & 7); + + } else if ((val & 0xf8) == 0x20) { + logmsg(LOG_LCD, 10, "lcd: select regulator resistor %x\n", val & 7); + + } else if ((val & 0xfe) == 0xac) { + if (val & 1) + lcd->flags |= LCDFLG_SET_STATIC_IND_MODE; + + } else if (val == 0xe3) { + logmsg(LOG_LCD, 10, "lcd: nop\n"); + + } else if ((val & 0xf0) == 0xf0 || (val & 0xf0) == 0x90) { + logmsg(LOG_LCD, 5, "lcd: test instruction\n"); + + } else + logmsg(LOG_LCD, 5, "lcd: write control %x\n", val); + } +} + +static void lcd_write_data(struct lcd *lcd, uint32 val) { + if (lcd->page < 9 && lcd->col < 132) { + logmsg(LOG_LCD, 10, "lcd: write data %x\n", val); + lcd->ddram[132 * lcd->page + lcd->col] = val; + lcd->col++; + } else + logmsg(LOG_LCD, 5, "lcd: out of display write data %x\n", val); +} + +void lcd_write(struct lcd *lcd, uint32 adr, uint32 val) { + switch (adr & 0x3f) { + case 0x20: + lcd_write_control(lcd, val); + break; + case 0x30: + lcd_write_data(lcd, val); + break; + default: + logmsg(LOG_LCD, 5, "lcd: write %x to %x\n", val, adr); + break; + } +} + +struct lcd *create_lcd(void) { + struct lcd *lcd; + lcd = xmalloc(sizeof(struct lcd)); + if (!lcd) + return NULL; + + memset(lcd->ddram, 0, sizeof(lcd->ddram)); + + lcd->flags = 0; + return lcd; +} + +void free_lcd(struct lcd *lcd) { + if (lcd) free(lcd); +} + +int lcd_get_pixel(struct lcd *lcd, int x, int y) { + return (lcd->ddram[132 * (y / 8) + x] >> (y % 8)) & 1; +} + +static print_small_chars[5] = {'.', 'o', 'o', 'O', '#'}; + +void lcd_print_small(struct lcd *lcd, FILE *fp) { + int x, y; + for (y = 0; y < 32; y++) { + for (x = 0; x < 64; x++) { + int c = 0; + if (lcd_get_pixel(lcd, x * 2, y * 2)) c++; + if (lcd_get_pixel(lcd, x * 2 + 1, y * 2)) c++; + if (lcd_get_pixel(lcd, x * 2, y * 2 + 1)) c++; + if (lcd_get_pixel(lcd, x * 2 + 1, y * 2 + 1)) c++; + fputc(print_small_chars[c], fp); + } + fputc('\n', fp); + } +} Index: utils/emuriver/src/flashimgtool/flashimg.h =================================================================== --- utils/emuriver/src/flashimgtool/flashimg.h (revision 0) +++ utils/emuriver/src/flashimgtool/flashimg.h (revision 0) @@ -0,0 +1,30 @@ +#ifndef _FLASHIMG_H_ +#define _FLASHIMG_H_ + +#include + +#define FLASHIMG_256_8 0 +#define FLASHIMG_512_8 1 +#define FLASHIMG_1024_8 2 + +#define FLASHIMG_PAGE_DATA_SIZE 2048 +#define FLASHIMG_PAGE_OOB_SIZE 64 +#define FLASHIMG_PAGE_SIZE (FLASHIMG_PAGE_OOB_SIZE + FLASHIMG_PAGE_DATA_SIZE) + +struct flashimg { + int model; + FILE *fp; + size_t offset; +}; + +struct flashimg *flashimg_create(int model, char *fname, int offset); +void flashimg_free(struct flashimg *flash); +int flashimg_write(struct flashimg *flash, const char *buf, + int page, int start, int length); +int flashimg_read(struct flashimg *flash, char *buf, + int page, int start, int length); + + + + +#endif Index: utils/emuriver/src/flashimgtool/disk.h =================================================================== --- utils/emuriver/src/flashimgtool/disk.h (revision 0) +++ utils/emuriver/src/flashimgtool/disk.h (revision 0) @@ -0,0 +1,41 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: disk.h,v 1.6 2005-01-28 21:32:16 hohensoh Exp $ + * + * Copyright (C) 2002 by Björn Stenberg + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#ifndef _DISK_H_ +#define _DISK_H_ + +#include "ata.h" /* for volume definitions */ + +struct partinfo { + unsigned long start; /* first sector (LBA) */ + unsigned long size; /* number of sectors */ + unsigned char type; +}; + +#define PARTITION_TYPE_FAT32 0x0b +#define PARTITION_TYPE_FAT32_LBA 0x0c +#define PARTITION_TYPE_FAT16 0x06 + +/* returns a pointer to an array of 8 partinfo structs */ +struct partinfo* disk_init(IF_MV_NONVOID(int volume)); +struct partinfo* disk_partinfo(int partition); +int disk_mount_all(void); /* returns the # of successful mounts */ +int disk_mount(int drive); +int disk_unmount(int drive); + +#endif Index: utils/emuriver/src/flashimgtool/Makefile.in =================================================================== --- utils/emuriver/src/flashimgtool/Makefile.in (revision 0) +++ utils/emuriver/src/flashimgtool/Makefile.in (revision 0) @@ -0,0 +1,304 @@ +# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999, 2001 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. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = ../.. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +CC = @CC@ +CURSES_LIB = @CURSES_LIB@ +HAVE_LIB = @HAVE_LIB@ +LIB = @LIB@ +LTLIB = @LTLIB@ +MAKEINFO = @MAKEINFO@ +PACKAGE = @PACKAGE@ +RANLIB = @RANLIB@ +SDL_CFLAGS = @SDL_CFLAGS@ +SDL_CONFIG = @SDL_CONFIG@ +SDL_LIBS = @SDL_LIBS@ +UI_OBJS = @UI_OBJS@ +VERSION = @VERSION@ + +bin_PROGRAMS = flashimgtool + +flashimgtool_SOURCES = flashimgtool.c flashimgtool.h disk.h disk.c fat.h fat.c ata.h ata.c file.h file.c dir.h dir.c unicode.c rbunicode.h flashimg.c flashimg.h flashdisk.c flashdisk.h + +flashimgtool_LDADD = ../common/libcommon.a + +INCLUDES = -I$(top_srcdir)/src/common +mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs +CONFIG_HEADER = ../../config.h +CONFIG_CLEAN_FILES = +PROGRAMS = $(bin_PROGRAMS) + + +DEFS = @DEFS@ -I. -I$(srcdir) -I../.. +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +flashimgtool_OBJECTS = flashimgtool.o disk.o fat.o ata.o file.o dir.o \ +unicode.o flashimg.o flashdisk.o +flashimgtool_DEPENDENCIES = ../common/libcommon.a +flashimgtool_LDFLAGS = +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP_ENV = --best +SOURCES = $(flashimgtool_SOURCES) +OBJECTS = $(flashimgtool_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .o .s +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps src/flashimgtool/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-binPROGRAMS: + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) + +distclean-binPROGRAMS: + +maintainer-clean-binPROGRAMS: + +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(bindir) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ + $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + else :; fi; \ + done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + list='$(bin_PROGRAMS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + done + +.c.o: + $(COMPILE) -c $< + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +flashimgtool: $(flashimgtool_OBJECTS) $(flashimgtool_DEPENDENCIES) + @rm -f flashimgtool + $(LINK) $(flashimgtool_LDFLAGS) $(flashimgtool_OBJECTS) $(flashimgtool_LDADD) $(LIBS) + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags -o $$here/TAGS $(ETAGS_ARGS) $$tags $$unique $(LISP)) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = src/flashimgtool + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +ata.o: ata.c ata.h flashdisk.h flashimgtool.h ../../config.h +dir.o: dir.c fat.h ata.h flashdisk.h dir.h file.h flashimgtool.h \ + ../../config.h +disk.o: disk.c ata.h flashdisk.h fat.h file.h dir.h disk.h \ + flashimgtool.h ../../config.h +fat.o: fat.c fat.h ata.h flashdisk.h rbunicode.h flashimgtool.h \ + ../../config.h +file.o: file.c file.h fat.h ata.h flashdisk.h dir.h flashimgtool.h \ + ../../config.h +flashdisk.o: flashdisk.c flashimg.h flashdisk.h \ + ../../src/common/common.h flashimgtool.h ../../config.h +flashimg.o: flashimg.c flashimg.h flashimgtool.h ../../config.h \ + ../../src/common/common.h +flashimgtool.o: flashimgtool.c ../../src/common/common.h disk.h ata.h \ + flashdisk.h flashimg.h dir.h file.h fat.h +unicode.o: unicode.c file.h rbunicode.h flashimgtool.h ../../config.h + +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: install-binPROGRAMS +install-exec: install-exec-am + +install-data-am: +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-binPROGRAMS +uninstall: uninstall-am +all-am: Makefile $(PROGRAMS) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + $(mkinstalldirs) $(DESTDIR)$(bindir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-compile \ + mostlyclean-tags mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-binPROGRAMS clean-compile clean-tags clean-generic \ + mostlyclean-am + +clean: clean-am + +distclean-am: distclean-binPROGRAMS distclean-compile distclean-tags \ + distclean-generic clean-am + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-binPROGRAMS \ + maintainer-clean-compile maintainer-clean-tags \ + maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \ +maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \ +mostlyclean-compile distclean-compile clean-compile \ +maintainer-clean-compile tags mostlyclean-tags distclean-tags \ +clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \ +check-am installcheck-am installcheck install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +# 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: Index: utils/emuriver/src/flashimgtool/ata.c =================================================================== --- utils/emuriver/src/flashimgtool/ata.c (revision 0) +++ utils/emuriver/src/flashimgtool/ata.c (revision 0) @@ -0,0 +1,37 @@ +#include "ata.h" +#include "flashdisk.h" +#include "flashimgtool.h" + +static struct flash_disk *flash_disk; + +void ata_init(struct flash_disk *flash_disk_) { + flash_disk = flash_disk_; +} + +int ata_read_sectors(unsigned long start, int incount, void *inbuf) { + DEBUGF("ata_read_sectors(%d, %d)\n", start, incount); + while (incount > 0) + { + int done = flash_disk_read_sectors(flash_disk, start, incount, inbuf); + if (done < 0) + return -1; + start += done; + incount -= done; + inbuf += SECTOR_SIZE * done; + } + return 0; +} + +int ata_write_sectors(unsigned long start, int count, void *buf) { + DEBUGF("ata_write_sectors(%d, %d)\n", start, count); + while (count > 0) + { + int done = flash_disk_write_sectors(flash_disk, start, count, buf); + if (done < 0) + return -1; + start += done; + count -= done; + buf += SECTOR_SIZE * done; + } + return 0; +} Index: utils/emuriver/src/flashimgtool/flashdisk.c =================================================================== --- utils/emuriver/src/flashimgtool/flashdisk.c (revision 0) +++ utils/emuriver/src/flashimgtool/flashdisk.c (revision 0) @@ -0,0 +1,383 @@ +#include "flashimg.h" +#include "flashdisk.h" +#include "common.h" +#include "flashimgtool.h" + +#define SECTOR_SIZE 512 + +static int flash_read_sector_oob(struct flash_disk *flash_disk, + int sector, unsigned char *oob) { + return flashimg_read(flash_disk->flash_img, oob, + sector / 4, 2048 + 16 * (sector % 4), 16); +} + +static int flash_read_sector(struct flash_disk *flash_disk, + int sector, + unsigned char *buf, unsigned char *oob) { + if (flashimg_read(flash_disk->flash_img, buf, + sector / 4, 512 * (sector % 4), 512) < 0) + return -1; + if (flashimg_read(flash_disk->flash_img, oob, + sector / 4, 2048 + 16 * (sector % 4), 16) < 0) + return -1; + return 0; +} + +static int flash_program_page(struct flash_disk *flash_disk, + int sector, + const unsigned char *buf, + const unsigned char *oob) { + if (flashimg_write(flash_disk->flash_img, buf, + sector / 4, 0, 2048) < 0) + return -1; + if (flashimg_write(flash_disk->flash_img, oob, + sector / 4, 2048, 64) < 0) + return -1; + return 0; +} + +static int flash_update_program_page(struct flash_disk *flash_disk, + int dest_sector, + int upd_start, int upd_length, + unsigned char *page, + const unsigned char *buf, + const unsigned char *oob) { + if (upd_length) { + memcpy(page + 512 * upd_start, buf, 512 * upd_length); + memcpy(page + 2048 + 16 * upd_start, oob + 16 * upd_start, + 16 * upd_length); + } + return flash_program_page(flash_disk, dest_sector, page, page + 2048); +} + +static int flash_copy_update_page(struct flash_disk *flash_disk, + int src_sector, int dest_sector, + int upd_start, int upd_length, + const unsigned char *buf, + const unsigned char *oob) { + unsigned char page[2048 + 64]; + if (flashimg_read(flash_disk->flash_img, page, + src_sector / 4, 0, 2048 + 64) < 0) + return -1; + return flash_update_program_page(flash_disk, dest_sector, + upd_start, upd_length, + page, buf, oob); +} + +static int flash_update_empty_page(struct flash_disk *flash_disk, + int dest_sector, + int upd_start, int upd_length, + const unsigned char *buf, + const unsigned char *oob) { + unsigned char page[2048 + 64]; + memset(page, 0xff, sizeof(page)); + return flash_update_program_page(flash_disk, dest_sector, + upd_start, upd_length, + page, buf, oob); +} + +static int flash_block_erase(struct flash_disk *flash_disk, + int sector) { + int ps; + unsigned char buf[2048 + 64]; + + memset(buf, 0xff, sizeof(buf)); + for (ps = sector; ps < sector + 64 * 4; ps += 4) + if (flash_program_page(flash_disk, ps, buf, buf + 2048) < 0) + return -1; + return 0; +} + +static int flash_disk_get_n_segments(struct flash_disk *flash_disk) +{ + switch (flash_disk->model) { + case FLASHIMG_256_8: + return 2; + case FLASHIMG_512_8: + return 4; + case FLASHIMG_1024_8: + return 8; + } +} + +static inline int flash_disk_get_n_phblocks(struct flash_disk *flash_disk) { + return 1024; +} + +static inline int flash_disk_get_n_sectors_in_block(struct flash_disk + *flash_disk) { + return 256; +} + +static int flash_disk_phblock_to_sector(struct flash_disk *flash_disk, + int segment, int block) +{ + return (segment * flash_disk_get_n_phblocks(flash_disk) + block) + * flash_disk_get_n_sectors_in_block(flash_disk); +} + +static int flash_disk_is_bad_block(unsigned char* oob) +{ + /* TODO: should we check two pages? (see datasheet) */ + return oob[0] != 0xff; +} + +static int count_1(int n) { + int r = 0; + while (n != 0) { + r += (n & 1); + n >>= 1; + } + return r; +} + +static int flash_disk_get_logical_block_no(unsigned char* oob) +{ + int no1, no2; + no1 = oob[6] + (oob[7] << 8); + no2 = oob[11] + (oob[12] << 8); + + if (no1 == no2 && (no1 & 0xf000) == 0x1000) + return (no1 & 0xfff) >> 1; + + if (count_1(no1 ^ no2) > 1) + return -1; + + if ((no1 & 0xf000) == 0x1000 + && (count_1(no1) & 1) == 0) + return (no1 & 0xfff) >> 1; + + if ((no2 & 0xf000) == 0x1000 + && (count_1(no2) & 1) == 0) + return (no2 & 0xfff) >> 1; + + return -1; +} + +static void flash_disk_set_oob(struct flash_disk *flash_disk, + char *oob, int sector) +{ + int blockmod, enc; + oob[0] = oob[5] = 0xff; + oob[1] = 0x5a; + + blockmod = (sector / flash_disk_get_n_sectors_in_block(flash_disk)) + % SEGMENT_SIZE; + enc = 0x1000 + (blockmod << 1); + if (count_1(enc) & 1) enc |= 1; + oob[6] = oob[11] = enc & 0xff; + oob[7] = oob[12] = enc >> 8; +} + +int flash_disk_scan(struct flash_disk *flash_disk) +{ + int n_segments, n_phblocks; + unsigned char oob[16]; + int s, b; + + /* TODO: checking for double blocks */ + + n_segments = flash_disk_get_n_segments(flash_disk); + n_phblocks = flash_disk_get_n_phblocks(flash_disk); + + flash_disk->cur_block = -1; + flash_disk->cur_phblock_start = -1; + + for (s = 0; s < n_segments; s++) + { + for (b = 0; b < n_phblocks; b++) + { + int r; + r = flash_read_sector_oob(flash_disk, + flash_disk_phblock_to_sector(flash_disk, + s, b), + oob); + if (r >= 0 && !flash_disk_is_bad_block(oob)) + { + int lb; + lb = flash_disk_get_logical_block_no(oob); + if (lb >= 0 && lb < SEGMENT_SIZE) { + DEBUGF("logical %d - physical %d\n", lb, b); + flash_disk->block_map[s][lb] = b; + } + } + } + } + return 0; +} + +int flash_disk_find_block(struct flash_disk *flash_disk, int block) +{ + int seg, bmod, phb; + unsigned char oob[16]; + int r; + + if (block >= SEGMENT_SIZE * flash_disk_get_n_segments(flash_disk)) + return -1; + + if (block == flash_disk->cur_block) + return flash_disk->cur_phblock_start; + + seg = block / SEGMENT_SIZE; + bmod = block % SEGMENT_SIZE; + + phb = flash_disk->block_map[seg][bmod]; + r = flash_read_sector_oob(flash_disk, + flash_disk_phblock_to_sector(flash_disk, + seg, phb), + oob); + if (r < 0) + return -1; + if (flash_disk_is_bad_block(oob)) + return -1; + if (flash_disk_get_logical_block_no(oob) != bmod) + return -1; + + flash_disk->cur_block = block; + flash_disk->cur_phblock_start = flash_disk_phblock_to_sector(flash_disk, + seg, phb); + return flash_disk->cur_phblock_start; +} + +int flash_disk_find_free_block(struct flash_disk *flash_disk, int block) +{ + int seg, b; + unsigned char oob[16]; + + if (block >= SEGMENT_SIZE * flash_disk_get_n_segments(flash_disk)) + return -1; + + seg = block / SEGMENT_SIZE; + /* TODO: wear leveling: start searching from random block? + * continue where the last free block was found? */ + for (b = 0; b < flash_disk_get_n_phblocks(flash_disk); b++) { + int r, s; + s = flash_disk_phblock_to_sector(flash_disk, seg, b); + r = flash_read_sector_oob(flash_disk, s, oob); + if (!flash_disk_is_bad_block(oob) && oob[1] == 0xff) + return s; + } + + return -1; +} + +int flash_disk_read_sectors(struct flash_disk *flash_disk, + unsigned long start, + int count, + void* buf) +{ + int block, secmod, done; + int phb; + char oob[16]; + + block = start / flash_disk_get_n_sectors_in_block(flash_disk); + secmod = start % flash_disk_get_n_sectors_in_block(flash_disk); + + phb = flash_disk_find_block(flash_disk, block); + done = 0; + while (count > 0 && secmod < flash_disk_get_n_sectors_in_block(flash_disk)) + { + if (phb >= 0) + flash_read_sector(flash_disk, phb + secmod, buf, oob); + else + memset(buf, 0, SECTOR_SIZE); + + buf += SECTOR_SIZE; + count--; + secmod++; + done++; + } + return done; +} + +int flash_disk_write_sectors(struct flash_disk *flash_disk, + unsigned long start, + int count, + const void* buf) +{ + int srcph, destph, block, secmod; + int ps, i, r, done; + char oob[64]; + + block = start / flash_disk_get_n_sectors_in_block(flash_disk); + secmod = start % flash_disk_get_n_sectors_in_block(flash_disk); + + srcph = flash_disk_find_block(flash_disk, block); + destph = flash_disk_find_free_block(flash_disk, block); + if (destph < 0) + return -1; + + done = 0; + for (ps = 0; ps < flash_disk_get_n_sectors_in_block(flash_disk); ps += 4) + { + if (ps >= secmod && ps + 3 < secmod + count) + { + for (i = 0; i < 4; i++) + flash_disk_set_oob(flash_disk, oob + i * 16, start + done + i); + r = flash_program_page(flash_disk, destph + ps, buf, oob); + /* TODO: mark as bad and try again */ + if (r < 0) + return -1; + done += 4; + buf += SECTOR_SIZE * 4; + } + else + { + int a, b, n; + a = secmod - ps; + if (a < 0) a = 0; + b = secmod + count - ps; + if (b > 4) b = 4; + n = b - a; + if (n < 0) n = 0; + for (i = 0; i < 4; i++) + flash_disk_set_oob(flash_disk, + oob + i * 16, start + done + i - a); + if (srcph >= 0) + r = flash_copy_update_page(flash_disk, + srcph + ps, destph + ps, + a, n, buf, oob); + else + r = flash_update_empty_page(flash_disk, + destph + ps, a, n, buf, oob); + /* TODO: mark as bad and try again */ + if (r < 0) + return -1; + done += n; + buf += SECTOR_SIZE * n; + } + } + + if (srcph >= 0) + if (flash_block_erase(flash_disk, srcph) < 0) { + /* TODO: mark as bad */ + } + + flash_disk->block_map[block / SEGMENT_SIZE][block % SEGMENT_SIZE] = + (destph / flash_disk_get_n_sectors_in_block(flash_disk)) + % flash_disk_get_n_phblocks(flash_disk); + flash_disk->cur_block = block; + flash_disk->cur_phblock_start = destph; + return done; +} + +struct flash_disk *flash_disk_create(struct flashimg *flash_img) { + struct flash_disk *flash_disk; + flash_disk = xmalloc(sizeof(struct flash_disk)); + if (!flash_disk) + return NULL; + + flash_disk->flash_img = flash_img; + flash_disk->model = flash_img->model; + + if (flash_disk_scan(flash_disk) < 0) { + flash_disk_free(flash_disk); + return NULL; + } + return flash_disk; +} + +void flash_disk_free(struct flash_disk *flash_disk) { + flashimg_free(flash_disk->flash_img); + free(flash_disk); +} Index: utils/emuriver/src/flashimgtool/ata.h =================================================================== --- utils/emuriver/src/flashimgtool/ata.h (revision 0) +++ utils/emuriver/src/flashimgtool/ata.h (revision 0) @@ -0,0 +1,17 @@ +#ifndef _ATA_H_ +#define _ATA_H_ + +#include "flashdisk.h" + +#define SECTOR_SIZE 512 + +#define IF_MV_NONVOID(a) void +#define IF_MV(a) +#define IF_MV2(a, b) b +#define NUM_VOLUMES 1 + +void ata_init(struct flash_disk *flash_disk_); +int ata_read_sectors(unsigned long start, int count, void *buf); +int ata_write_sectors(unsigned long start, int count, void *buf); + +#endif Index: utils/emuriver/src/flashimgtool/fat.c =================================================================== --- utils/emuriver/src/flashimgtool/fat.c (revision 0) +++ utils/emuriver/src/flashimgtool/fat.c (revision 0) @@ -0,0 +1,2385 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: fat.c,v 1.127 2006-08-02 15:58:02 miipekk Exp $ + * + * Copyright (C) 2002 by Linus Nielsen Feltzing + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include +#include +#include +#include +#include +#include "fat.h" +#include "ata.h" +/* +#include "debug.h" +#include "panic.h" +#include "system.h" +#include "timefuncs.h" +#include "kernel.h" +#include "logf.h" +*/ +#include "rbunicode.h" +#include "flashimgtool.h" + +#define BYTES2INT16(array,pos) \ + (array[pos] | (array[pos+1] << 8 )) +#define BYTES2INT32(array,pos) \ + ((long)array[pos] | ((long)array[pos+1] << 8 ) | \ + ((long)array[pos+2] << 16 ) | ((long)array[pos+3] << 24 )) + +#define FATTYPE_FAT12 0 +#define FATTYPE_FAT16 1 +#define FATTYPE_FAT32 2 + +/* BPB offsets; generic */ +#define BS_JMPBOOT 0 +#define BS_OEMNAME 3 +#define BPB_BYTSPERSEC 11 +#define BPB_SECPERCLUS 13 +#define BPB_RSVDSECCNT 14 +#define BPB_NUMFATS 16 +#define BPB_ROOTENTCNT 17 +#define BPB_TOTSEC16 19 +#define BPB_MEDIA 21 +#define BPB_FATSZ16 22 +#define BPB_SECPERTRK 24 +#define BPB_NUMHEADS 26 +#define BPB_HIDDSEC 28 +#define BPB_TOTSEC32 32 + +/* fat12/16 */ +#define BS_DRVNUM 36 +#define BS_RESERVED1 37 +#define BS_BOOTSIG 38 +#define BS_VOLID 39 +#define BS_VOLLAB 43 +#define BS_FILSYSTYPE 54 + +/* fat32 */ +#define BPB_FATSZ32 36 +#define BPB_EXTFLAGS 40 +#define BPB_FSVER 42 +#define BPB_ROOTCLUS 44 +#define BPB_FSINFO 48 +#define BPB_BKBOOTSEC 50 +#define BS_32_DRVNUM 64 +#define BS_32_BOOTSIG 66 +#define BS_32_VOLID 67 +#define BS_32_VOLLAB 71 +#define BS_32_FILSYSTYPE 82 + +#define BPB_LAST_WORD 510 + + +/* attributes */ +#define FAT_ATTR_LONG_NAME (FAT_ATTR_READ_ONLY | FAT_ATTR_HIDDEN | \ + FAT_ATTR_SYSTEM | FAT_ATTR_VOLUME_ID) +#define FAT_ATTR_LONG_NAME_MASK (FAT_ATTR_READ_ONLY | FAT_ATTR_HIDDEN | \ + FAT_ATTR_SYSTEM | FAT_ATTR_VOLUME_ID | \ + FAT_ATTR_DIRECTORY | FAT_ATTR_ARCHIVE ) + +/* NTRES flags */ +#define FAT_NTRES_LC_NAME 0x08 +#define FAT_NTRES_LC_EXT 0x10 + +#define FATDIR_NAME 0 +#define FATDIR_ATTR 11 +#define FATDIR_NTRES 12 +#define FATDIR_CRTTIMETENTH 13 +#define FATDIR_CRTTIME 14 +#define FATDIR_CRTDATE 16 +#define FATDIR_LSTACCDATE 18 +#define FATDIR_FSTCLUSHI 20 +#define FATDIR_WRTTIME 22 +#define FATDIR_WRTDATE 24 +#define FATDIR_FSTCLUSLO 26 +#define FATDIR_FILESIZE 28 + +#define FATLONG_ORDER 0 +#define FATLONG_TYPE 12 +#define FATLONG_CHKSUM 13 + +#define CLUSTERS_PER_FAT_SECTOR (SECTOR_SIZE / 4) +#define CLUSTERS_PER_FAT16_SECTOR (SECTOR_SIZE / 2) +#define DIR_ENTRIES_PER_SECTOR (SECTOR_SIZE / DIR_ENTRY_SIZE) +#define DIR_ENTRY_SIZE 32 +#define NAME_BYTES_PER_ENTRY 13 +#define FAT_BAD_MARK 0x0ffffff7 +#define FAT_EOF_MARK 0x0ffffff8 +#define FAT_LONGNAME_PAD_BYTE 0xff +#define FAT_LONGNAME_PAD_UCS 0xffff + +struct fsinfo { + unsigned long freecount; /* last known free cluster count */ + unsigned long nextfree; /* first cluster to start looking for free + clusters, or 0xffffffff for no hint */ +}; +/* fsinfo offsets */ +#define FSINFO_FREECOUNT 488 +#define FSINFO_NEXTFREE 492 + +struct bpb +{ + int bpb_bytspersec; /* Bytes per sector, typically 512 */ + unsigned int bpb_secperclus; /* Sectors per cluster */ + int bpb_rsvdseccnt; /* Number of reserved sectors */ + int bpb_numfats; /* Number of FAT structures, typically 2 */ + int bpb_totsec16; /* Number of sectors on the volume (old 16-bit) */ + int bpb_media; /* Media type (typically 0xf0 or 0xf8) */ + int bpb_fatsz16; /* Number of used sectors per FAT structure */ + unsigned long bpb_totsec32; /* Number of sectors on the volume + (new 32-bit) */ + unsigned int last_word; /* 0xAA55 */ + + /**** FAT32 specific *****/ + long bpb_fatsz32; + long bpb_rootclus; + long bpb_fsinfo; + + /* variables for internal use */ + unsigned long fatsize; + unsigned long totalsectors; + unsigned long rootdirsector; + unsigned long firstdatasector; + unsigned long startsector; + unsigned long dataclusters; + struct fsinfo fsinfo; +#ifdef HAVE_FAT16SUPPORT + int bpb_rootentcnt; /* Number of dir entries in the root */ + /* internals for FAT16 support */ + bool is_fat16; /* true if we mounted a FAT16 partition, false if FAT32 */ + unsigned int rootdiroffset; /* sector offset of root dir relative to start + * of first pseudo cluster */ +#endif /* #ifdef HAVE_FAT16SUPPORT */ +#ifdef HAVE_MULTIVOLUME + int drive; /* on which physical device is this located */ + bool mounted; /* flag if this volume is mounted */ +#endif +}; + +static struct bpb fat_bpbs[NUM_VOLUMES]; /* mounted partition info */ + +static int update_fsinfo(IF_MV_NONVOID(struct bpb* fat_bpb)); +static int flush_fat(IF_MV_NONVOID(struct bpb* fat_bpb)); +static int bpb_is_sane(IF_MV_NONVOID(struct bpb* fat_bpb)); +static void *cache_fat_sector(IF_MV2(struct bpb* fat_bpb,) long secnum, bool dirty); +static void create_dos_name(const unsigned char *name, unsigned char *newname); +static void randomize_dos_name(unsigned char *name); +static unsigned long find_free_cluster(IF_MV2(struct bpb* fat_bpb,) unsigned long start); +static int transfer(IF_MV2(struct bpb* fat_bpb,) unsigned long start, long count, char* buf, bool write ); + +#define FAT_CACHE_SIZE 0x20 +#define FAT_CACHE_MASK (FAT_CACHE_SIZE-1) + +struct fat_cache_entry +{ + long secnum; + bool inuse; + bool dirty; +#ifdef HAVE_MULTIVOLUME + struct bpb* fat_vol ; /* shared cache for all volumes */ +#endif +}; + +static char fat_cache_sectors[FAT_CACHE_SIZE][SECTOR_SIZE]; +static struct fat_cache_entry fat_cache[FAT_CACHE_SIZE]; +static struct mutex cache_mutex; + +static long cluster2sec(IF_MV2(struct bpb* fat_bpb,) long cluster) +{ +#ifndef HAVE_MULTIVOLUME + struct bpb* fat_bpb = &fat_bpbs[0]; +#endif +#ifdef HAVE_FAT16SUPPORT + /* negative clusters (FAT16 root dir) don't get the 2 offset */ + int zerocluster = cluster < 0 ? 0 : 2; +#else + const long zerocluster = 2; +#endif + + if (cluster > (long)(fat_bpb->dataclusters + 1)) + { + DEBUGF( "cluster2sec() - Bad cluster number (%ld)\n", cluster); + return -1; + } + + return (cluster - zerocluster) * fat_bpb->bpb_secperclus + + fat_bpb->firstdatasector; +} + +long fat_startsector(IF_MV_NONVOID(int volume)) +{ +#ifndef HAVE_MULTIVOLUME + const int volume = 0; +#endif + struct bpb* fat_bpb = &fat_bpbs[volume]; + return fat_bpb->startsector; +} + +void fat_size(IF_MV2(int volume,) unsigned long* size, unsigned long* free) +{ +#ifndef HAVE_MULTIVOLUME + const int volume = 0; +#endif + struct bpb* fat_bpb = &fat_bpbs[volume]; + if (size) + *size = fat_bpb->dataclusters * fat_bpb->bpb_secperclus / 2; + if (free) + *free = fat_bpb->fsinfo.freecount * fat_bpb->bpb_secperclus / 2; +} + +void fat_init(void) +{ + unsigned int i; + + mutex_init(&cache_mutex); + + /* mark the FAT cache as unused */ + for(i = 0;i < FAT_CACHE_SIZE;i++) + { + fat_cache[i].secnum = 8; /* We use a "safe" sector just in case */ + fat_cache[i].inuse = false; + fat_cache[i].dirty = false; +#ifdef HAVE_MULTIVOLUME + fat_cache[i].fat_vol = NULL; +#endif + } +#ifdef HAVE_MULTIVOLUME + /* mark the possible volumes as not mounted */ + for (i=0; istartsector = startsector; +#ifdef HAVE_MULTIVOLUME + fat_bpb->drive = drive; +#endif + + fat_bpb->bpb_bytspersec = BYTES2INT16(buf,BPB_BYTSPERSEC); + fat_bpb->bpb_secperclus = buf[BPB_SECPERCLUS]; + fat_bpb->bpb_rsvdseccnt = BYTES2INT16(buf,BPB_RSVDSECCNT); + fat_bpb->bpb_numfats = buf[BPB_NUMFATS]; + fat_bpb->bpb_totsec16 = BYTES2INT16(buf,BPB_TOTSEC16); + fat_bpb->bpb_media = buf[BPB_MEDIA]; + fat_bpb->bpb_fatsz16 = BYTES2INT16(buf,BPB_FATSZ16); + fat_bpb->bpb_fatsz32 = BYTES2INT32(buf,BPB_FATSZ32); + fat_bpb->bpb_totsec32 = BYTES2INT32(buf,BPB_TOTSEC32); + fat_bpb->last_word = BYTES2INT16(buf,BPB_LAST_WORD); + + /* calculate a few commonly used values */ + if (fat_bpb->bpb_fatsz16 != 0) + fat_bpb->fatsize = fat_bpb->bpb_fatsz16; + else + fat_bpb->fatsize = fat_bpb->bpb_fatsz32; + + if (fat_bpb->bpb_totsec16 != 0) + fat_bpb->totalsectors = fat_bpb->bpb_totsec16; + else + fat_bpb->totalsectors = fat_bpb->bpb_totsec32; + +#ifdef HAVE_FAT16SUPPORT + fat_bpb->bpb_rootentcnt = BYTES2INT16(buf,BPB_ROOTENTCNT); + rootdirsectors = ((fat_bpb->bpb_rootentcnt * 32) + + (fat_bpb->bpb_bytspersec - 1)) / fat_bpb->bpb_bytspersec; +#endif /* #ifdef HAVE_FAT16SUPPORT */ + + fat_bpb->firstdatasector = fat_bpb->bpb_rsvdseccnt +#ifdef HAVE_FAT16SUPPORT + + rootdirsectors +#endif + + fat_bpb->bpb_numfats * fat_bpb->fatsize; + + /* Determine FAT type */ + datasec = fat_bpb->totalsectors - fat_bpb->firstdatasector; + fat_bpb->dataclusters = datasec / fat_bpb->bpb_secperclus; + +#ifdef TEST_FAT + /* + we are sometimes testing with "illegally small" fat32 images, + so we don't use the proper fat32 test case for test code + */ + if ( fat_bpb->bpb_fatsz16 ) +#else + if ( fat_bpb->dataclusters < 65525 ) +#endif + { /* FAT16 */ +#ifdef HAVE_FAT16SUPPORT + fat_bpb->is_fat16 = true; + if (fat_bpb->dataclusters < 4085) + { /* FAT12 */ + DEBUGF("This is FAT12. Go away!\n"); + return -2; + } +#else /* #ifdef HAVE_FAT16SUPPORT */ + DEBUGF("This is not FAT32. Go away!\n"); + return -2; +#endif /* #ifndef HAVE_FAT16SUPPORT */ + } + +#ifdef HAVE_FAT16SUPPORT + if (fat_bpb->is_fat16) + { /* FAT16 specific part of BPB */ + int dirclusters; + fat_bpb->rootdirsector = fat_bpb->bpb_rsvdseccnt + + fat_bpb->bpb_numfats * fat_bpb->bpb_fatsz16; + dirclusters = ((rootdirsectors + fat_bpb->bpb_secperclus - 1) + / fat_bpb->bpb_secperclus); /* rounded up, to full clusters */ + /* I assign negative pseudo cluster numbers for the root directory, + their range is counted upward until -1. */ + fat_bpb->bpb_rootclus = 0 - dirclusters; /* backwards, before the data */ + fat_bpb->rootdiroffset = dirclusters * fat_bpb->bpb_secperclus + - rootdirsectors; + } + else +#endif /* #ifdef HAVE_FAT16SUPPORT */ + { /* FAT32 specific part of BPB */ + fat_bpb->bpb_rootclus = BYTES2INT32(buf,BPB_ROOTCLUS); + fat_bpb->bpb_fsinfo = BYTES2INT16(buf,BPB_FSINFO); + fat_bpb->rootdirsector = cluster2sec(IF_MV2(fat_bpb,) fat_bpb->bpb_rootclus); + } + + rc = bpb_is_sane(IF_MV(fat_bpb)); + if (rc < 0) + { + DEBUGF( "fat_mount() - BPB is not sane\n"); + return rc * 10 - 3; + } + +#ifdef HAVE_FAT16SUPPORT + if (fat_bpb->is_fat16) + { + fat_bpb->fsinfo.freecount = 0xffffffff; /* force recalc below */ + fat_bpb->fsinfo.nextfree = 0xffffffff; + } + else +#endif /* #ifdef HAVE_FAT16SUPPORT */ + { + /* Read the fsinfo sector */ + rc = ata_read_sectors(IF_MV2(drive,) + startsector + fat_bpb->bpb_fsinfo, 1, buf); + if (rc < 0) + { + DEBUGF( "fat_mount() - Couldn't read FSInfo (error code %d)\n", rc); + return rc * 10 - 4; + } + fat_bpb->fsinfo.freecount = BYTES2INT32(buf, FSINFO_FREECOUNT); + fat_bpb->fsinfo.nextfree = BYTES2INT32(buf, FSINFO_NEXTFREE); + } + + /* calculate freecount if unset */ + if ( fat_bpb->fsinfo.freecount == 0xffffffff ) + { + fat_recalc_free(IF_MV(volume)); + } + + LDEBUGF("Freecount: %ld\n",fat_bpb->fsinfo.freecount); + LDEBUGF("Nextfree: 0x%lx\n",fat_bpb->fsinfo.nextfree); + LDEBUGF("Cluster count: 0x%lx\n",fat_bpb->dataclusters); + LDEBUGF("Sectors per cluster: %d\n",fat_bpb->bpb_secperclus); + LDEBUGF("FAT sectors: 0x%lx\n",fat_bpb->fatsize); + +#ifdef HAVE_MULTIVOLUME + fat_bpb->mounted = true; +#endif + + return 0; +} + +#ifdef HAVE_HOTSWAP +int fat_unmount(int volume, bool flush) +{ + int rc; + struct bpb* fat_bpb = &fat_bpbs[volume]; + + if(flush) + { + rc = flush_fat(fat_bpb); /* the clean way, while still alive */ + } + else + { /* volume is not accessible any more, e.g. MMC removed */ + int i; + mutex_lock(&cache_mutex); + for(i = 0;i < FAT_CACHE_SIZE;i++) + { + struct fat_cache_entry *fce = &fat_cache[i]; + if(fce->inuse && fce->fat_vol == fat_bpb) + { + fce->inuse = false; /* discard all from that volume */ + fce->dirty = false; + } + } + mutex_unlock(&cache_mutex); + rc = 0; + } + fat_bpb->mounted = false; + return rc; +} +#endif /* #ifdef HAVE_HOTSWAP */ + +void fat_recalc_free(IF_MV_NONVOID(int volume)) +{ +#ifndef HAVE_MULTIVOLUME + const int volume = 0; +#endif + struct bpb* fat_bpb = &fat_bpbs[volume]; + long free = 0; + unsigned long i; +#ifdef HAVE_FAT16SUPPORT + if (fat_bpb->is_fat16) + { + for (i = 0; ifatsize; i++) { + unsigned int j; + unsigned short* fat = cache_fat_sector(IF_MV2(fat_bpb,) i, false); + for (j = 0; j < CLUSTERS_PER_FAT16_SECTOR; j++) { + unsigned int c = i * CLUSTERS_PER_FAT16_SECTOR + j; + if ( c > fat_bpb->dataclusters+1 ) /* nr 0 is unused */ + break; + + if (letoh16(fat[j]) == 0x0000) { + free++; + if ( fat_bpb->fsinfo.nextfree == 0xffffffff ) + fat_bpb->fsinfo.nextfree = c; + } + } + } + } + else +#endif /* #ifdef HAVE_FAT16SUPPORT */ + { + for (i = 0; ifatsize; i++) { + unsigned int j; + unsigned long* fat = cache_fat_sector(IF_MV2(fat_bpb,) i, false); + for (j = 0; j < CLUSTERS_PER_FAT_SECTOR; j++) { + unsigned long c = i * CLUSTERS_PER_FAT_SECTOR + j; + if ( c > fat_bpb->dataclusters+1 ) /* nr 0 is unused */ + break; + + if (!(letoh32(fat[j]) & 0x0fffffff)) { + free++; + if ( fat_bpb->fsinfo.nextfree == 0xffffffff ) + fat_bpb->fsinfo.nextfree = c; + } + } + } + } + fat_bpb->fsinfo.freecount = free; + update_fsinfo(IF_MV(fat_bpb)); +} + +static int bpb_is_sane(IF_MV_NONVOID(struct bpb* fat_bpb)) +{ +#ifndef HAVE_MULTIVOLUME + struct bpb* fat_bpb = &fat_bpbs[0]; +#endif + if(fat_bpb->bpb_bytspersec != 512) + { + DEBUGF( "bpb_is_sane() - Error: sector size is not 512 (%d)\n", + fat_bpb->bpb_bytspersec); + return -1; + } + if((long)fat_bpb->bpb_secperclus * (long)fat_bpb->bpb_bytspersec > 128L*1024L) + { + DEBUGF( "bpb_is_sane() - Error: cluster size is larger than 128K " + "(%d * %d = %d)\n", + fat_bpb->bpb_bytspersec, fat_bpb->bpb_secperclus, + fat_bpb->bpb_bytspersec * fat_bpb->bpb_secperclus); + return -2; + } + if(fat_bpb->bpb_numfats != 2) + { + DEBUGF( "bpb_is_sane() - Warning: NumFATS is not 2 (%d)\n", + fat_bpb->bpb_numfats); + } + if(fat_bpb->bpb_media != 0xf0 && fat_bpb->bpb_media < 0xf8) + { + DEBUGF( "bpb_is_sane() - Warning: Non-standard " + "media type (0x%02x)\n", + fat_bpb->bpb_media); + } + if(fat_bpb->last_word != 0xaa55) + { + DEBUGF( "bpb_is_sane() - Error: Last word is not " + "0xaa55 (0x%04x)\n", fat_bpb->last_word); + return -3; + } + + if (fat_bpb->fsinfo.freecount > + (fat_bpb->totalsectors - fat_bpb->firstdatasector)/ + fat_bpb->bpb_secperclus) + { + DEBUGF( "bpb_is_sane() - Error: FSInfo.Freecount > disk size " + "(0x%04lx)\n", fat_bpb->fsinfo.freecount); + return -4; + } + + return 0; +} + +static void flush_fat_sector(struct fat_cache_entry *fce, + unsigned char *sectorbuf) +{ + int rc; + long secnum; + + /* With multivolume, use only the FAT info from the cached sector! */ +#ifdef HAVE_MULTIVOLUME + secnum = fce->secnum + fce->fat_vol->startsector; +#else + secnum = fce->secnum + fat_bpbs[0].startsector; +#endif + + /* Write to the first FAT */ + rc = ata_write_sectors(IF_MV2(fce->fat_vol->drive,) + secnum, 1, + sectorbuf); + if(rc < 0) + { + panicf("flush_fat_sector() - Could not write sector %ld" + " (error %d)\n", + secnum, rc); + } +#ifdef HAVE_MULTIVOLUME + if(fce->fat_vol->bpb_numfats > 1) +#else + if(fat_bpbs[0].bpb_numfats > 1) +#endif + { + /* Write to the second FAT */ +#ifdef HAVE_MULTIVOLUME + secnum += fce->fat_vol->fatsize; +#else + secnum += fat_bpbs[0].fatsize; +#endif + rc = ata_write_sectors(IF_MV2(fce->fat_vol->drive,) + secnum, 1, sectorbuf); + if(rc < 0) + { + panicf("flush_fat_sector() - Could not write sector %ld" + " (error %d)\n", + secnum, rc); + } + } + fce->dirty = false; +} + +/* Note: The returned pointer is only safely valid until the next + task switch! (Any subsequent ata read/write may yield.) */ +static void *cache_fat_sector(IF_MV2(struct bpb* fat_bpb,) + long fatsector, bool dirty) +{ +#ifndef HAVE_MULTIVOLUME + struct bpb* fat_bpb = &fat_bpbs[0]; +#endif + long secnum = fatsector + fat_bpb->bpb_rsvdseccnt; + int cache_index = secnum & FAT_CACHE_MASK; + struct fat_cache_entry *fce = &fat_cache[cache_index]; + unsigned char *sectorbuf = &fat_cache_sectors[cache_index][0]; + int rc; + + mutex_lock(&cache_mutex); /* make changes atomic */ + + /* Delete the cache entry if it isn't the sector we want */ + if(fce->inuse && (fce->secnum != secnum +#ifdef HAVE_MULTIVOLUME + || fce->fat_vol != fat_bpb +#endif + )) + { + /* Write back if it is dirty */ + if(fce->dirty) + { + flush_fat_sector(fce, sectorbuf); + } + fce->inuse = false; + } + + /* Load the sector if it is not cached */ + if(!fce->inuse) + { + rc = ata_read_sectors(IF_MV2(fat_bpb->drive,) + secnum + fat_bpb->startsector,1, + sectorbuf); + if(rc < 0) + { + DEBUGF( "cache_fat_sector() - Could not read sector %ld" + " (error %d)\n", secnum, rc); + mutex_unlock(&cache_mutex); + return NULL; + } + fce->inuse = true; + fce->secnum = secnum; +#ifdef HAVE_MULTIVOLUME + fce->fat_vol = fat_bpb; +#endif + } + if (dirty) + fce->dirty = true; /* dirt remains, sticky until flushed */ + mutex_unlock(&cache_mutex); + return sectorbuf; +} + +static unsigned long find_free_cluster(IF_MV2(struct bpb* fat_bpb,) unsigned long startcluster) +{ +#ifndef HAVE_MULTIVOLUME + struct bpb* fat_bpb = &fat_bpbs[0]; +#endif + unsigned long sector; + unsigned long offset; + unsigned long i; + +#ifdef HAVE_FAT16SUPPORT + if (fat_bpb->is_fat16) + { + sector = startcluster / CLUSTERS_PER_FAT16_SECTOR; + offset = startcluster % CLUSTERS_PER_FAT16_SECTOR; + + for (i = 0; ifatsize; i++) { + unsigned int j; + unsigned int nr = (i + sector) % fat_bpb->fatsize; + unsigned short* fat = cache_fat_sector(IF_MV2(fat_bpb,) nr, false); + if ( !fat ) + break; + for (j = 0; j < CLUSTERS_PER_FAT16_SECTOR; j++) { + int k = (j + offset) % CLUSTERS_PER_FAT16_SECTOR; + if (letoh16(fat[k]) == 0x0000) { + unsigned int c = nr * CLUSTERS_PER_FAT16_SECTOR + k; + /* Ignore the reserved clusters 0 & 1, and also + cluster numbers out of bounds */ + if ( c < 2 || c > fat_bpb->dataclusters+1 ) + continue; + LDEBUGF("find_free_cluster(%x) == %x\n",startcluster,c); + fat_bpb->fsinfo.nextfree = c; + return c; + } + } + offset = 0; + } + } + else +#endif /* #ifdef HAVE_FAT16SUPPORT */ + { + sector = startcluster / CLUSTERS_PER_FAT_SECTOR; + offset = startcluster % CLUSTERS_PER_FAT_SECTOR; + + for (i = 0; ifatsize; i++) { + unsigned int j; + unsigned long nr = (i + sector) % fat_bpb->fatsize; + unsigned long* fat = cache_fat_sector(IF_MV2(fat_bpb,) nr, false); + if ( !fat ) + break; + for (j = 0; j < CLUSTERS_PER_FAT_SECTOR; j++) { + int k = (j + offset) % CLUSTERS_PER_FAT_SECTOR; + if (!(letoh32(fat[k]) & 0x0fffffff)) { + unsigned long c = nr * CLUSTERS_PER_FAT_SECTOR + k; + /* Ignore the reserved clusters 0 & 1, and also + cluster numbers out of bounds */ + if ( c < 2 || c > fat_bpb->dataclusters+1 ) + continue; + LDEBUGF("find_free_cluster(%lx) == %lx\n",startcluster,c); + fat_bpb->fsinfo.nextfree = c; + return c; + } + } + offset = 0; + } + } + + LDEBUGF("find_free_cluster(%lx) == 0\n",startcluster); + return 0; /* 0 is an illegal cluster number */ +} + +static int update_fat_entry(IF_MV2(struct bpb* fat_bpb,) unsigned long entry, unsigned long val) +{ +#ifndef HAVE_MULTIVOLUME + struct bpb* fat_bpb = &fat_bpbs[0]; +#endif +#ifdef HAVE_FAT16SUPPORT + if (fat_bpb->is_fat16) + { + int sector = entry / CLUSTERS_PER_FAT16_SECTOR; + int offset = entry % CLUSTERS_PER_FAT16_SECTOR; + unsigned short* sec; + + val &= 0xFFFF; + + LDEBUGF("update_fat_entry(%x,%x)\n",entry,val); + + if (entry==val) + panicf("Creating FAT loop: %lx,%lx\n",entry,val); + + if ( entry < 2 ) + panicf("Updating reserved FAT entry %ld.\n",entry); + + sec = cache_fat_sector(IF_MV2(fat_bpb,) sector, true); + if (!sec) + { + DEBUGF( "update_fat_entry() - Could not cache sector %d\n", sector); + return -1; + } + + if ( val ) { + if (letoh16(sec[offset]) == 0x0000 && fat_bpb->fsinfo.freecount > 0) + fat_bpb->fsinfo.freecount--; + } + else { + if (letoh16(sec[offset])) + fat_bpb->fsinfo.freecount++; + } + + LDEBUGF("update_fat_entry: %d free clusters\n", fat_bpb->fsinfo.freecount); + + sec[offset] = htole16(val); + } + else +#endif /* #ifdef HAVE_FAT16SUPPORT */ + { + long sector = entry / CLUSTERS_PER_FAT_SECTOR; + int offset = entry % CLUSTERS_PER_FAT_SECTOR; + unsigned long* sec; + + LDEBUGF("update_fat_entry(%lx,%lx)\n",entry,val); + + if (entry==val) + panicf("Creating FAT loop: %lx,%lx\n",entry,val); + + if ( entry < 2 ) + panicf("Updating reserved FAT entry %ld.\n",entry); + + sec = cache_fat_sector(IF_MV2(fat_bpb,) sector, true); + if (!sec) + { + DEBUGF( "update_fat_entry() - Could not cache sector %ld\n", sector); + return -1; + } + + if ( val ) { + if (!(letoh32(sec[offset]) & 0x0fffffff) && + fat_bpb->fsinfo.freecount > 0) + fat_bpb->fsinfo.freecount--; + } + else { + if (letoh32(sec[offset]) & 0x0fffffff) + fat_bpb->fsinfo.freecount++; + } + + LDEBUGF("update_fat_entry: %ld free clusters\n", fat_bpb->fsinfo.freecount); + + /* don't change top 4 bits */ + sec[offset] &= htole32(0xf0000000); + sec[offset] |= htole32(val & 0x0fffffff); + } + + return 0; +} + +static long read_fat_entry(IF_MV2(struct bpb* fat_bpb,) unsigned long entry) +{ +#ifdef HAVE_FAT16SUPPORT +#ifndef HAVE_MULTIVOLUME + struct bpb* fat_bpb = &fat_bpbs[0]; +#endif + if (fat_bpb->is_fat16) + { + int sector = entry / CLUSTERS_PER_FAT16_SECTOR; + int offset = entry % CLUSTERS_PER_FAT16_SECTOR; + unsigned short* sec; + + sec = cache_fat_sector(IF_MV2(fat_bpb,) sector, false); + if (!sec) + { + DEBUGF( "read_fat_entry() - Could not cache sector %d\n", sector); + return -1; + } + + return letoh16(sec[offset]); + } + else +#endif /* #ifdef HAVE_FAT16SUPPORT */ + { + long sector = entry / CLUSTERS_PER_FAT_SECTOR; + int offset = entry % CLUSTERS_PER_FAT_SECTOR; + unsigned long* sec; + + sec = cache_fat_sector(IF_MV2(fat_bpb,) sector, false); + if (!sec) + { + DEBUGF( "read_fat_entry() - Could not cache sector %ld\n", sector); + return -1; + } + + return letoh32(sec[offset]) & 0x0fffffff; + } +} + +static long get_next_cluster(IF_MV2(struct bpb* fat_bpb,) long cluster) +{ + long next_cluster; + long eof_mark = FAT_EOF_MARK; + +#ifdef HAVE_FAT16SUPPORT +#ifndef HAVE_MULTIVOLUME + struct bpb* fat_bpb = &fat_bpbs[0]; +#endif + if (fat_bpb->is_fat16) + { + eof_mark &= 0xFFFF; /* only 16 bit */ + if (cluster < 0) /* FAT16 root dir */ + return cluster + 1; /* don't use the FAT */ + } +#endif + next_cluster = read_fat_entry(IF_MV2(fat_bpb,) cluster); + + /* is this last cluster in chain? */ + if ( next_cluster >= eof_mark ) + return 0; + else + return next_cluster; +} + +static int update_fsinfo(IF_MV_NONVOID(struct bpb* fat_bpb)) +{ +#ifndef HAVE_MULTIVOLUME + struct bpb* fat_bpb = &fat_bpbs[0]; +#endif + unsigned char fsinfo[SECTOR_SIZE]; + unsigned long* intptr; + int rc; + +#ifdef HAVE_FAT16SUPPORT + if (fat_bpb->is_fat16) + return 0; /* FAT16 has no FsInfo */ +#endif /* #ifdef HAVE_FAT16SUPPORT */ + + /* update fsinfo */ + rc = ata_read_sectors(IF_MV2(fat_bpb->drive,) + fat_bpb->startsector + fat_bpb->bpb_fsinfo, 1,fsinfo); + if (rc < 0) + { + DEBUGF( "flush_fat() - Couldn't read FSInfo (error code %d)\n", rc); + return rc * 10 - 1; + } + intptr = (long*)&(fsinfo[FSINFO_FREECOUNT]); + *intptr = htole32(fat_bpb->fsinfo.freecount); + + intptr = (long*)&(fsinfo[FSINFO_NEXTFREE]); + *intptr = htole32(fat_bpb->fsinfo.nextfree); + + rc = ata_write_sectors(IF_MV2(fat_bpb->drive,) + fat_bpb->startsector + fat_bpb->bpb_fsinfo,1,fsinfo); + if (rc < 0) + { + DEBUGF( "flush_fat() - Couldn't write FSInfo (error code %d)\n", rc); + return rc * 10 - 2; + } + + return 0; +} + +static int flush_fat(IF_MV_NONVOID(struct bpb* fat_bpb)) +{ + int i; + int rc; + unsigned char *sec; + LDEBUGF("flush_fat()\n"); + + mutex_lock(&cache_mutex); + for(i = 0;i < FAT_CACHE_SIZE;i++) + { + struct fat_cache_entry *fce = &fat_cache[i]; + if(fce->inuse +#ifdef HAVE_MULTIVOLUME + && fce->fat_vol == fat_bpb +#endif + && fce->dirty) + { + sec = fat_cache_sectors[i]; + flush_fat_sector(fce, sec); + } + } + mutex_unlock(&cache_mutex); + + rc = update_fsinfo(IF_MV(fat_bpb)); + if (rc < 0) + return rc * 10 - 3; + + return 0; +} + +static void fat_time(unsigned short* date, + unsigned short* time, + unsigned short* tenth ) +{ +#ifdef CONFIG_RTC + struct tm* tm = get_time(); + + if (date) + *date = ((tm->tm_year - 80) << 9) | + ((tm->tm_mon + 1) << 5) | + tm->tm_mday; + + if (time) + *time = (tm->tm_hour << 11) | + (tm->tm_min << 5) | + (tm->tm_sec >> 1); + + if (tenth) + *tenth = (tm->tm_sec & 1) * 100; +#else + /* non-RTC version returns an increment from the supplied time, or a + * fixed standard time/date if no time given as input */ + bool next_day = false; + + if (time) + { + if (0 == *time) + { + /* set to 00:15:00 */ + *time = (15 << 5); + } + else + { + unsigned short mins = (*time >> 5) & 0x003F; + unsigned short hours = (*time >> 11) & 0x001F; + if ((mins += 10) >= 60) + { + mins = 0; + hours++; + } + if ((++hours) >= 24) + { + hours = hours - 24; + next_day = true; + } + *time = (hours << 11) | (mins << 5); + } + } + + if (date) + { + if (0 == *date) + { +/* Macros to convert a 2-digit string to a decimal constant. + (YEAR), MONTH and DAY are set by the date command, which outputs + DAY as 00..31 and MONTH as 01..12. The leading zero would lead to + misinterpretation as an octal constant. */ +#define S100(x) 1 ## x +#define C2DIG2DEC(x) (S100(x)-100) + /* set to build date */ + *date = ((YEAR - 1980) << 9) | (C2DIG2DEC(MONTH) << 5) + | C2DIG2DEC(DAY); + } + else + { + unsigned short day = *date & 0x001F; + unsigned short month = (*date >> 5) & 0x000F; + unsigned short year = (*date >> 9) & 0x007F; + if (next_day) + { + /* do a very simple day increment - never go above 28 days */ + if (++day > 28) + { + day = 1; + if (++month > 12) + { + month = 1; + year++; + } + } + *date = (year << 9) | (month << 5) | day; + } + } + } + if (tenth) + *tenth = 0; +#endif /* CONFIG_RTC */ +} + +static int write_long_name(struct fat_file* file, + unsigned int firstentry, + unsigned int numentries, + const unsigned char* name, + const unsigned char* shortname, + bool is_directory) +{ + unsigned char buf[SECTOR_SIZE]; + unsigned char* entry; + unsigned int idx = firstentry % DIR_ENTRIES_PER_SECTOR; + unsigned int sector = firstentry / DIR_ENTRIES_PER_SECTOR; + unsigned char chksum = 0; + unsigned int i, j=0; + unsigned int nameidx=0, namelen = utf8length(name); + int rc; + unsigned short name_utf16[namelen + 1]; + + LDEBUGF("write_long_name(file:%lx, first:%d, num:%d, name:%s)\n", + file->firstcluster, firstentry, numentries, name); + + rc = fat_seek(file, sector); + if (rc<0) + return rc * 10 - 1; + + rc = fat_readwrite(file, 1, buf, false); + if (rc<1) + return rc * 10 - 2; + + /* calculate shortname checksum */ + for (i=11; i>0; i--) + chksum = ((chksum & 1) ? 0x80 : 0) + (chksum >> 1) + shortname[j++]; + + /* calc position of last name segment */ + if ( namelen > NAME_BYTES_PER_ENTRY ) + for (nameidx=0; + nameidx < (namelen - NAME_BYTES_PER_ENTRY); + nameidx += NAME_BYTES_PER_ENTRY); + + /* we need to convert the name first */ + /* since it is written in reverse order */ + for (i = 0; i <= namelen; i++) + name = utf8decode(name, &name_utf16[i]); + + for (i=0; i < numentries; i++) { + /* new sector? */ + if ( idx >= DIR_ENTRIES_PER_SECTOR ) { + /* update current sector */ + rc = fat_seek(file, sector); + if (rc<0) + return rc * 10 - 3; + + rc = fat_readwrite(file, 1, buf, true); + if (rc<1) + return rc * 10 - 4; + + /* read next sector */ + rc = fat_readwrite(file, 1, buf, false); + if (rc<0) { + LDEBUGF("Failed writing new sector: %d\n",rc); + return rc * 10 - 5; + } + if (rc==0) + /* end of dir */ + memset(buf, 0, sizeof buf); + + sector++; + idx = 0; + } + + entry = buf + idx * DIR_ENTRY_SIZE; + + /* verify this entry is free */ + if (entry[0] && entry[0] != 0xe5 ) + panicf("Dir entry %d in sector %x is not free! " + "%02x %02x %02x %02x", + idx, sector, + entry[0], entry[1], entry[2], entry[3]); + + memset(entry, 0, DIR_ENTRY_SIZE); + if ( i+1 < numentries ) { + /* longname entry */ + unsigned int k, l = nameidx; + + entry[FATLONG_ORDER] = numentries-i-1; + if (i==0) { + /* mark this as last long entry */ + entry[FATLONG_ORDER] |= 0x40; + + /* pad name with 0xffff */ + for (k=1; k<11; k++) entry[k] = FAT_LONGNAME_PAD_BYTE; + for (k=14; k<26; k++) entry[k] = FAT_LONGNAME_PAD_BYTE; + for (k=28; k<32; k++) entry[k] = FAT_LONGNAME_PAD_BYTE; + }; + /* set name */ + for (k=0; k<5 && l <= namelen; k++) { + entry[k*2 + 1] = (unsigned char)(name_utf16[l] & 0xff); + entry[k*2 + 2] = (unsigned char)(name_utf16[l++] >> 8); + } + for (k=0; k<6 && l <= namelen; k++) { + entry[k*2 + 14] = (unsigned char)(name_utf16[l] & 0xff); + entry[k*2 + 15] = (unsigned char)(name_utf16[l++] >> 8); + } + for (k=0; k<2 && l <= namelen; k++) { + entry[k*2 + 28] = (unsigned char)(name_utf16[l] & 0xff); + entry[k*2 + 29] = (unsigned char)(name_utf16[l++] >> 8); + } + + entry[FATDIR_ATTR] = FAT_ATTR_LONG_NAME; + entry[FATDIR_FSTCLUSLO] = 0; + entry[FATLONG_TYPE] = 0; + entry[FATLONG_CHKSUM] = chksum; + LDEBUGF("Longname entry %d: %s\n", idx, name+nameidx); + } + else { + /* shortname entry */ + unsigned short date=0, time=0, tenth=0; + LDEBUGF("Shortname entry: %s\n", shortname); + strncpy(entry + FATDIR_NAME, shortname, 11); + entry[FATDIR_ATTR] = is_directory?FAT_ATTR_DIRECTORY:0; + entry[FATDIR_NTRES] = 0; + + fat_time(&date, &time, &tenth); + entry[FATDIR_CRTTIMETENTH] = tenth; + *(unsigned short*)(entry + FATDIR_CRTTIME) = htole16(time); + *(unsigned short*)(entry + FATDIR_WRTTIME) = htole16(time); + *(unsigned short*)(entry + FATDIR_CRTDATE) = htole16(date); + *(unsigned short*)(entry + FATDIR_WRTDATE) = htole16(date); + *(unsigned short*)(entry + FATDIR_LSTACCDATE) = htole16(date); + } + idx++; + nameidx -= NAME_BYTES_PER_ENTRY; + } + + /* update last sector */ + rc = fat_seek(file, sector); + if (rc<0) + return rc * 10 - 6; + + rc = fat_readwrite(file, 1, buf, true); + if (rc<1) + return rc * 10 - 7; + + return 0; +} + +static int fat_checkname(const unsigned char* newname) +{ + /* More sanity checks are probably needed */ + if ( newname[strlen(newname) - 1] == '.' ) { + return -1; + } + return 0; +} + +static int add_dir_entry(struct fat_dir* dir, + struct fat_file* file, + const char* name, + bool is_directory, + bool dotdir) +{ +#ifdef HAVE_MULTIVOLUME + struct bpb* fat_bpb = &fat_bpbs[dir->file.volume]; +#else + struct bpb* fat_bpb = &fat_bpbs[0]; +#endif + unsigned char buf[SECTOR_SIZE]; + unsigned char shortname[12]; + int rc; + unsigned int sector; + bool done = false; + int entries_needed, entries_found = 0; + int firstentry; + + LDEBUGF( "add_dir_entry(%s,%lx)\n", + name, file->firstcluster); + + /* Don't check dotdirs name for validity */ + if (dotdir == false) { + rc = fat_checkname(name); + if (rc < 0) { + /* filename is invalid */ + return rc * 10 - 1; + } + } + +#ifdef HAVE_MULTIVOLUME + file->volume = dir->file.volume; /* inherit the volume, to make sure */ +#endif + + /* The "." and ".." directory entries must not be long names */ + if(dotdir) { + int i; + strncpy(shortname, name, 12); + for(i = strlen(shortname); i < 12; i++) + shortname[i] = ' '; + + entries_needed = 1; + } else { + create_dos_name(name, shortname); + + /* one dir entry needed for every 13 bytes of filename, + plus one entry for the short name */ + entries_needed = (utf8length(name) + (NAME_BYTES_PER_ENTRY-1)) + / NAME_BYTES_PER_ENTRY + 1; + } + + restart: + firstentry = -1; + + rc = fat_seek(&dir->file, 0); + if (rc < 0) + return rc * 10 - 2; + + /* step 1: search for free entries and check for duplicate shortname */ + for (sector = 0; !done; sector++) + { + unsigned int i; + + rc = fat_readwrite(&dir->file, 1, buf, false); + if (rc < 0) { + DEBUGF( "add_dir_entry() - Couldn't read dir" + " (error code %d)\n", rc); + return rc * 10 - 3; + } + + if (rc == 0) { /* current end of dir reached */ + LDEBUGF("End of dir on cluster boundary\n"); + break; + } + + /* look for free slots */ + for (i = 0; i < DIR_ENTRIES_PER_SECTOR; i++) + { + switch (buf[i * DIR_ENTRY_SIZE]) { + case 0: + entries_found += DIR_ENTRIES_PER_SECTOR - i; + LDEBUGF("Found end of dir %d\n", + sector * DIR_ENTRIES_PER_SECTOR + i); + i = DIR_ENTRIES_PER_SECTOR - 1; + done = true; + break; + + case 0xe5: + entries_found++; + LDEBUGF("Found free entry %d (%d/%d)\n", + sector * DIR_ENTRIES_PER_SECTOR + i, + entries_found, entries_needed); + break; + + default: + entries_found = 0; + + /* check that our intended shortname doesn't already exist */ + if (!strncmp(shortname, buf + i * DIR_ENTRY_SIZE, 11)) { + /* shortname exists already, make a new one */ + randomize_dos_name(shortname); + LDEBUGF("Duplicate shortname, changing to %s\n", + shortname); + + /* name has changed, we need to restart search */ + goto restart; + } + break; + } + if (firstentry < 0 && (entries_found >= entries_needed)) + firstentry = sector * DIR_ENTRIES_PER_SECTOR + i + 1 + - entries_found; + } + } + + /* step 2: extend the dir if necessary */ + if (firstentry < 0) + { + LDEBUGF("Adding new sector(s) to dir\n"); + rc = fat_seek(&dir->file, sector); + if (rc < 0) + return rc * 10 - 4; + memset(buf, 0, sizeof buf); + + /* we must clear whole clusters */ + for (; (entries_found < entries_needed) || + (dir->file.sectornum < (int)fat_bpb->bpb_secperclus); sector++) + { + if (sector >= (65536/DIR_ENTRIES_PER_SECTOR)) + return -5; /* dir too large -- FAT specification */ + + rc = fat_readwrite(&dir->file, 1, buf, true); + if (rc < 1) /* No more room or something went wrong */ + return rc * 10 - 6; + + entries_found += DIR_ENTRIES_PER_SECTOR; + } + + firstentry = sector * DIR_ENTRIES_PER_SECTOR - entries_found; + } + + /* step 3: add entry */ + sector = firstentry / DIR_ENTRIES_PER_SECTOR; + LDEBUGF("Adding longname to entry %d in sector %d\n", + firstentry, sector); + + rc = write_long_name(&dir->file, firstentry, + entries_needed, name, shortname, is_directory); + if (rc < 0) + return rc * 10 - 7; + + /* remember where the shortname dir entry is located */ + file->direntry = firstentry + entries_needed - 1; + file->direntries = entries_needed; + file->dircluster = dir->file.firstcluster; + LDEBUGF("Added new dir entry %d, using %d slots.\n", + file->direntry, file->direntries); + + return 0; +} + +unsigned char char2dos(unsigned char c) +{ + switch(c) + { + case 0x22: + case 0x2a: + case 0x2b: + case 0x2c: + case 0x2e: + case 0x3a: + case 0x3b: + case 0x3c: + case 0x3d: + case 0x3e: + case 0x3f: + case 0x5b: + case 0x5c: + case 0x5d: + case 0x7c: + /* Illegal char, replace */ + c = '_'; + break; + + default: + if(c <= 0x20) + c = 0; /* Illegal char, remove */ + else + c = toupper(c); + break; + } + return c; +} + +static void create_dos_name(const unsigned char *name, unsigned char *newname) +{ + int i; + unsigned char *ext; + + /* Find extension part */ + ext = strrchr(name, '.'); + if (ext == name) /* handle .dotnames */ + ext = NULL; + + /* Name part */ + for (i = 0; *name && (!ext || name < ext) && (i < 8); name++) + { + unsigned char c = char2dos(*name); + if (c) + newname[i++] = c; + } + + /* Pad both name and extension */ + while (i < 11) + newname[i++] = ' '; + + if (newname[0] == 0xe5) /* Special kanji character */ + newname[0] = 0x05; + + if (ext) + { /* Extension part */ + ext++; + for (i = 8; *ext && (i < 11); ext++) + { + unsigned char c = char2dos(*ext); + if (c) + newname[i++] = c; + } + } +} + +static void randomize_dos_name(unsigned char *name) +{ + int i; + unsigned char buf[5]; + + snprintf(buf, sizeof buf, "%04X", (unsigned)rand() & 0xffff); + + for (i = 0; (i < 4) && (name[i] != ' '); i++); + /* account for possible shortname length < 4 */ + memcpy(&name[i], buf, 4); +} + +static int update_short_entry( struct fat_file* file, long size, int attr ) +{ + unsigned char buf[SECTOR_SIZE]; + int sector = file->direntry / DIR_ENTRIES_PER_SECTOR; + unsigned char* entry = + buf + DIR_ENTRY_SIZE * (file->direntry % DIR_ENTRIES_PER_SECTOR); + unsigned long* sizeptr; + unsigned short* clusptr; + struct fat_file dir; + int rc; + + LDEBUGF("update_file_size(cluster:%lx entry:%d size:%ld)\n", + file->firstcluster, file->direntry, size); + + /* create a temporary file handle for the dir holding this file */ + rc = fat_open(IF_MV2(file->volume,) file->dircluster, &dir, NULL); + if (rc < 0) + return rc * 10 - 1; + + rc = fat_seek( &dir, sector ); + if (rc<0) + return rc * 10 - 2; + + rc = fat_readwrite(&dir, 1, buf, false); + if (rc < 1) + return rc * 10 - 3; + + if (!entry[0] || entry[0] == 0xe5) + panicf("Updating size on empty dir entry %d\n", file->direntry); + + entry[FATDIR_ATTR] = attr & 0xFF; + + clusptr = (short*)(entry + FATDIR_FSTCLUSHI); + *clusptr = htole16(file->firstcluster >> 16); + + clusptr = (short*)(entry + FATDIR_FSTCLUSLO); + *clusptr = htole16(file->firstcluster & 0xffff); + + sizeptr = (long*)(entry + FATDIR_FILESIZE); + *sizeptr = htole32(size); + + { +#ifdef CONFIG_RTC + unsigned short time = 0; + unsigned short date = 0; +#else + /* get old time to increment from */ + unsigned short time = htole16(*(unsigned short*)(entry + FATDIR_WRTTIME)); + unsigned short date = htole16(*(unsigned short*)(entry + FATDIR_WRTDATE)); +#endif + fat_time(&date, &time, NULL); + *(unsigned short*)(entry + FATDIR_WRTTIME) = htole16(time); + *(unsigned short*)(entry + FATDIR_WRTDATE) = htole16(date); + *(unsigned short*)(entry + FATDIR_LSTACCDATE) = htole16(date); + } + + rc = fat_seek( &dir, sector ); + if (rc < 0) + return rc * 10 - 4; + + rc = fat_readwrite(&dir, 1, buf, true); + if (rc < 1) + return rc * 10 - 5; + + return 0; +} + +static int parse_direntry(struct fat_direntry *de, const unsigned char *buf) +{ + int i=0,j=0; + unsigned char c; + bool lowercase; + + memset(de, 0, sizeof(struct fat_direntry)); + de->attr = buf[FATDIR_ATTR]; + de->crttimetenth = buf[FATDIR_CRTTIMETENTH]; + de->crtdate = BYTES2INT16(buf,FATDIR_CRTDATE); + de->crttime = BYTES2INT16(buf,FATDIR_CRTTIME); + de->wrtdate = BYTES2INT16(buf,FATDIR_WRTDATE); + de->wrttime = BYTES2INT16(buf,FATDIR_WRTTIME); + de->filesize = BYTES2INT32(buf,FATDIR_FILESIZE); + de->firstcluster = ((long)(unsigned)BYTES2INT16(buf,FATDIR_FSTCLUSLO)) | + ((long)(unsigned)BYTES2INT16(buf,FATDIR_FSTCLUSHI) << 16); + /* The double cast is to prevent a sign-extension to be done on CalmRISC16. + (the result of the shift is always considered signed) */ + + /* fix the name */ + lowercase = (buf[FATDIR_NTRES] & FAT_NTRES_LC_NAME); + c = buf[FATDIR_NAME]; + if (c == 0x05) /* special kanji char */ + c = 0xe5; + i = 0; + while (c != ' ') { + de->name[j++] = lowercase ? tolower(c) : c; + if (++i >= 8) + break; + c = buf[FATDIR_NAME+i]; + } + if (buf[FATDIR_NAME+8] != ' ') { + lowercase = (buf[FATDIR_NTRES] & FAT_NTRES_LC_EXT); + de->name[j++] = '.'; + for (i = 8; (i < 11) && ((c = buf[FATDIR_NAME+i]) != ' '); i++) + de->name[j++] = lowercase ? tolower(c) : c; + } + return 1; +} + +int fat_open(IF_MV2(int volume,) + long startcluster, + struct fat_file *file, + const struct fat_dir* dir) +{ + file->firstcluster = startcluster; + file->lastcluster = startcluster; + file->lastsector = 0; + file->clusternum = 0; + file->sectornum = 0; + file->eof = false; +#ifdef HAVE_MULTIVOLUME + file->volume = volume; + /* fixme: remove error check when done */ + if (volume >= NUM_VOLUMES || !fat_bpbs[volume].mounted) + { + LDEBUGF("fat_open() illegal volume %d\n", volume); + return -1; + } +#endif + + /* remember where the file's dir entry is located */ + if ( dir ) { + file->direntry = dir->entry - 1; + file->direntries = dir->entrycount; + file->dircluster = dir->file.firstcluster; + } + LDEBUGF("fat_open(%lx), entry %d\n",startcluster,file->direntry); + return 0; +} + +int fat_create_file(const char* name, + struct fat_file* file, + struct fat_dir* dir) +{ + int rc; + + LDEBUGF("fat_create_file(\"%s\",%lx,%lx)\n",name,(long)file,(long)dir); + rc = add_dir_entry(dir, file, name, false, false); + if (!rc) { + file->firstcluster = 0; + file->lastcluster = 0; + file->lastsector = 0; + file->clusternum = 0; + file->sectornum = 0; + file->eof = false; + } + + return rc; +} + +int fat_create_dir(const char* name, + struct fat_dir* newdir, + struct fat_dir* dir) +{ +#ifdef HAVE_MULTIVOLUME + struct bpb* fat_bpb = &fat_bpbs[dir->file.volume]; +#else + struct bpb* fat_bpb = &fat_bpbs[0]; +#endif + unsigned char buf[SECTOR_SIZE]; + int i; + long sector; + int rc; + struct fat_file dummyfile; + + LDEBUGF("fat_create_dir(\"%s\",%lx,%lx)\n",name,(long)newdir,(long)dir); + + memset(newdir, 0, sizeof(struct fat_dir)); + memset(&dummyfile, 0, sizeof(struct fat_file)); + + /* First, add the entry in the parent directory */ + rc = add_dir_entry(dir, &newdir->file, name, true, false); + if (rc < 0) + return rc * 10 - 1; + + /* Allocate a new cluster for the directory */ + newdir->file.firstcluster = find_free_cluster(IF_MV2(fat_bpb,) fat_bpb->fsinfo.nextfree); + if(newdir->file.firstcluster == 0) + return -1; + + update_fat_entry(IF_MV2(fat_bpb,) newdir->file.firstcluster, FAT_EOF_MARK); + + /* Clear the entire cluster */ + memset(buf, 0, sizeof buf); + sector = cluster2sec(IF_MV2(fat_bpb,) newdir->file.firstcluster); + for(i = 0;i < (int)fat_bpb->bpb_secperclus;i++) { + rc = transfer(IF_MV2(fat_bpb,) sector + i, 1, buf, true ); + if (rc < 0) + return rc * 10 - 2; + } + + /* Then add the "." entry */ + rc = add_dir_entry(newdir, &dummyfile, ".", true, true); + if (rc < 0) + return rc * 10 - 3; + dummyfile.firstcluster = newdir->file.firstcluster; + update_short_entry(&dummyfile, 0, FAT_ATTR_DIRECTORY); + + /* and the ".." entry */ + rc = add_dir_entry(newdir, &dummyfile, "..", true, true); + if (rc < 0) + return rc * 10 - 4; + + /* The root cluster is cluster 0 in the ".." entry */ + if(dir->file.firstcluster == fat_bpb->bpb_rootclus) + dummyfile.firstcluster = 0; + else + dummyfile.firstcluster = dir->file.firstcluster; + update_short_entry(&dummyfile, 0, FAT_ATTR_DIRECTORY); + + /* Set the firstcluster field in the direntry */ + update_short_entry(&newdir->file, 0, FAT_ATTR_DIRECTORY); + + rc = flush_fat(IF_MV(fat_bpb)); + if (rc < 0) + return rc * 10 - 5; + + return rc; +} + +int fat_truncate(const struct fat_file *file) +{ + /* truncate trailing clusters */ + long next; + long last = file->lastcluster; +#ifdef HAVE_MULTIVOLUME + struct bpb* fat_bpb = &fat_bpbs[file->volume]; +#endif + + LDEBUGF("fat_truncate(%lx, %lx)\n", file->firstcluster, last); + + for ( last = get_next_cluster(IF_MV2(fat_bpb,) last); last; last = next ) { + next = get_next_cluster(IF_MV2(fat_bpb,) last); + update_fat_entry(IF_MV2(fat_bpb,) last,0); + } + if (file->lastcluster) + update_fat_entry(IF_MV2(fat_bpb,) file->lastcluster,FAT_EOF_MARK); + + return 0; +} + +int fat_closewrite(struct fat_file *file, long size, int attr) +{ + int rc; +#ifdef HAVE_MULTIVOLUME + struct bpb* fat_bpb = &fat_bpbs[file->volume]; +#endif + LDEBUGF("fat_closewrite(size=%ld)\n",size); + + if (!size) { + /* empty file */ + if ( file->firstcluster ) { + update_fat_entry(IF_MV2(fat_bpb,) file->firstcluster, 0); + file->firstcluster = 0; + } + } + + if (file->dircluster) { + rc = update_short_entry(file, size, attr); + if (rc < 0) + return rc * 10 - 1; + } + + flush_fat(IF_MV(fat_bpb)); + +#ifdef TEST_FAT + if ( file->firstcluster ) { + /* debug */ +#ifdef HAVE_MULTIVOLUME + struct bpb* fat_bpb = &fat_bpbs[file->volume]; +#else + struct bpb* fat_bpb = &fat_bpbs[0]; +#endif + long count = 0; + long len; + long next; + for ( next = file->firstcluster; next; + next = get_next_cluster(IF_MV2(fat_bpb,) next) ) { + LDEBUGF("cluster %ld: %lx\n", count, next); + count++; + } + len = count * fat_bpb->bpb_secperclus * SECTOR_SIZE; + LDEBUGF("File is %ld clusters (chainlen=%ld, size=%ld)\n", + count, len, size ); + if ( len > size + fat_bpb->bpb_secperclus * SECTOR_SIZE) + panicf("Cluster chain is too long\n"); + if ( len < size ) + panicf("Cluster chain is too short\n"); + } +#endif + + return 0; +} + +static int free_direntries(struct fat_file* file) +{ + unsigned char buf[SECTOR_SIZE]; + struct fat_file dir; + int numentries = file->direntries; + unsigned int entry = file->direntry - numentries + 1; + unsigned int sector = entry / DIR_ENTRIES_PER_SECTOR; + int i; + int rc; + + /* create a temporary file handle for the dir holding this file */ + rc = fat_open(IF_MV2(file->volume,) file->dircluster, &dir, NULL); + if (rc < 0) + return rc * 10 - 1; + + rc = fat_seek( &dir, sector ); + if (rc < 0) + return rc * 10 - 2; + + rc = fat_readwrite(&dir, 1, buf, false); + if (rc < 1) + return rc * 10 - 3; + + for (i=0; i < numentries; i++) { + LDEBUGF("Clearing dir entry %d (%d/%d)\n", + entry, i+1, numentries); + buf[(entry % DIR_ENTRIES_PER_SECTOR) * DIR_ENTRY_SIZE] = 0xe5; + entry++; + + if ( (entry % DIR_ENTRIES_PER_SECTOR) == 0 ) { + /* flush this sector */ + rc = fat_seek(&dir, sector); + if (rc < 0) + return rc * 10 - 4; + + rc = fat_readwrite(&dir, 1, buf, true); + if (rc < 1) + return rc * 10 - 5; + + if ( i+1 < numentries ) { + /* read next sector */ + rc = fat_readwrite(&dir, 1, buf, false); + if (rc < 1) + return rc * 10 - 6; + } + sector++; + } + } + + if ( entry % DIR_ENTRIES_PER_SECTOR ) { + /* flush this sector */ + rc = fat_seek(&dir, sector); + if (rc < 0) + return rc * 10 - 7; + + rc = fat_readwrite(&dir, 1, buf, true); + if (rc < 1) + return rc * 10 - 8; + } + + return 0; +} + +int fat_remove(struct fat_file* file) +{ + long next, last = file->firstcluster; + int rc; +#ifdef HAVE_MULTIVOLUME + struct bpb* fat_bpb = &fat_bpbs[file->volume]; +#endif + + LDEBUGF("fat_remove(%lx)\n",last); + + while ( last ) { + next = get_next_cluster(IF_MV2(fat_bpb,) last); + update_fat_entry(IF_MV2(fat_bpb,) last,0); + last = next; + } + + if ( file->dircluster ) { + rc = free_direntries(file); + if (rc < 0) + return rc * 10 - 1; + } + + file->firstcluster = 0; + file->dircluster = 0; + + rc = flush_fat(IF_MV(fat_bpb)); + if (rc < 0) + return rc * 10 - 2; + + return 0; +} + +int fat_rename(struct fat_file* file, + struct fat_dir* dir, + const unsigned char* newname, + long size, + int attr) +{ + int rc; + struct fat_dir olddir; + struct fat_file newfile = *file; +#ifdef HAVE_MULTIVOLUME + struct bpb* fat_bpb = &fat_bpbs[file->volume]; + + if (file->volume != dir->file.volume) { + DEBUGF("No rename across volumes!\n"); + return -1; + } +#endif + + if ( !file->dircluster ) { + DEBUGF("File has no dir cluster!\n"); + return -2; + } + + /* create a temporary file handle */ + rc = fat_opendir(IF_MV2(file->volume,) &olddir, file->dircluster, NULL); + if (rc < 0) + return rc * 10 - 3; + + /* create new name */ + rc = add_dir_entry(dir, &newfile, newname, false, false); + if (rc < 0) + return rc * 10 - 4; + + /* write size and cluster link */ + rc = update_short_entry(&newfile, size, attr); + if (rc < 0) + return rc * 10 - 5; + + /* remove old name */ + rc = free_direntries(file); + if (rc < 0) + return rc * 10 - 6; + + rc = flush_fat(IF_MV(fat_bpb)); + if (rc < 0) + return rc * 10 - 7; + + return 0; +} + +static long next_write_cluster(struct fat_file* file, + long oldcluster, + long* newsector) +{ +#ifdef HAVE_MULTIVOLUME + struct bpb* fat_bpb = &fat_bpbs[file->volume]; +#else + struct bpb* fat_bpb = &fat_bpbs[0]; +#endif + long cluster = 0; + long sector; + + LDEBUGF("next_write_cluster(%lx,%lx)\n",file->firstcluster, oldcluster); + + if (oldcluster) + cluster = get_next_cluster(IF_MV2(fat_bpb,) oldcluster); + + if (!cluster) { + if (oldcluster > 0) + cluster = find_free_cluster(IF_MV2(fat_bpb,) oldcluster+1); + else if (oldcluster == 0) + cluster = find_free_cluster(IF_MV2(fat_bpb,) fat_bpb->fsinfo.nextfree); +#ifdef HAVE_FAT16SUPPORT + else /* negative, pseudo-cluster of the root dir */ + return 0; /* impossible to append something to the root */ +#endif + + if (cluster) { + if (oldcluster) + update_fat_entry(IF_MV2(fat_bpb,) oldcluster, cluster); + else + file->firstcluster = cluster; + update_fat_entry(IF_MV2(fat_bpb,) cluster, FAT_EOF_MARK); + } + else { +#ifdef TEST_FAT + if (fat_bpb->fsinfo.freecount>0) + panicf("There is free space, but find_free_cluster() " + "didn't find it!\n"); +#endif + DEBUGF("next_write_cluster(): Disk full!\n"); + return 0; + } + } + sector = cluster2sec(IF_MV2(fat_bpb,) cluster); + if (sector<0) + return 0; + + *newsector = sector; + return cluster; +} + +static int transfer(IF_MV2(struct bpb* fat_bpb,) + unsigned long start, long count, char* buf, bool write ) +{ +#ifndef HAVE_MULTIVOLUME + struct bpb* fat_bpb = &fat_bpbs[0]; +#endif + int rc; + + LDEBUGF("transfer(s=%lx, c=%lx, %s)\n", + start+ fat_bpb->startsector, count, write?"write":"read"); + if (write) { + unsigned long firstallowed; +#ifdef HAVE_FAT16SUPPORT + if (fat_bpb->is_fat16) + firstallowed = fat_bpb->rootdirsector; + else +#endif + firstallowed = fat_bpb->firstdatasector; + + if (start < firstallowed) + panicf("Write %ld before data\n", firstallowed - start); + if (start + count > fat_bpb->totalsectors) + panicf("Write %ld after data\n", + start + count - fat_bpb->totalsectors); + rc = ata_write_sectors(IF_MV2(fat_bpb->drive,) + start + fat_bpb->startsector, count, buf); + } + else + rc = ata_read_sectors(IF_MV2(fat_bpb->drive,) + start + fat_bpb->startsector, count, buf); + if (rc < 0) { + DEBUGF( "transfer() - Couldn't %s sector %lx" + " (error code %d)\n", + write ? "write":"read", start, rc); + return rc; + } + return 0; +} + + +long fat_readwrite( struct fat_file *file, long sectorcount, + void* buf, bool write ) +{ +#ifdef HAVE_MULTIVOLUME + struct bpb* fat_bpb = &fat_bpbs[file->volume]; +#else + struct bpb* fat_bpb = &fat_bpbs[0]; +#endif + long cluster = file->lastcluster; + long sector = file->lastsector; + long clusternum = file->clusternum; + long numsec = file->sectornum; + bool eof = file->eof; + long first=0, last=0; + long i; + int rc; + + LDEBUGF( "fat_readwrite(file:%lx,count:0x%lx,buf:%lx,%s)\n", + file->firstcluster,sectorcount,(long)buf,write?"write":"read"); + LDEBUGF( "fat_readwrite: sec=%lx numsec=%ld eof=%d\n", + sector,numsec, eof?1:0); + + if ( eof && !write) + return 0; + + /* find sequential sectors and write them all at once */ + for (i=0; (i < sectorcount) && (sector > -1); i++ ) { + numsec++; + if ( numsec > (long)fat_bpb->bpb_secperclus || !cluster ) { + long oldcluster = cluster; + if (write) + cluster = next_write_cluster(file, cluster, §or); + else { + cluster = get_next_cluster(IF_MV2(fat_bpb,) cluster); + sector = cluster2sec(IF_MV2(fat_bpb,) cluster); + } + + clusternum++; + numsec=1; + + if (!cluster) { + eof = true; + if ( write ) { + /* remember last cluster, in case + we want to append to the file */ + cluster = oldcluster; + clusternum--; + i = -1; /* Error code */ + break; + } + } + else + eof = false; + } + else { + if (sector) + sector++; + else { + /* look up first sector of file */ + sector = cluster2sec(IF_MV2(fat_bpb,) file->firstcluster); + numsec=1; +#ifdef HAVE_FAT16SUPPORT + if (file->firstcluster < 0) + { /* FAT16 root dir */ + sector += fat_bpb->rootdiroffset; + numsec += fat_bpb->rootdiroffset; + } +#endif + } + } + + if (!first) + first = sector; + + if ( ((sector != first) && (sector != last+1)) || /* not sequential */ + (last-first+1 == 256) ) { /* max 256 sectors per ata request */ + long count = last - first + 1; + rc = transfer(IF_MV2(fat_bpb,) first, count, buf, write ); + if (rc < 0) + return rc * 10 - 1; + + buf = (char *)buf + count * SECTOR_SIZE; + first = sector; + } + + if ((i == sectorcount-1) && /* last sector requested */ + (!eof)) + { + long count = sector - first + 1; + rc = transfer(IF_MV2(fat_bpb,) first, count, buf, write ); + if (rc < 0) + return rc * 10 - 2; + } + + last = sector; + } + + file->lastcluster = cluster; + file->lastsector = sector; + file->clusternum = clusternum; + file->sectornum = numsec; + file->eof = eof; + + /* if eof, don't report last block as read/written */ + if (eof) + i--; + + DEBUGF("Sectors written: %ld\n", i); + return i; +} + +int fat_seek(struct fat_file *file, unsigned long seeksector ) +{ +#ifdef HAVE_MULTIVOLUME + struct bpb* fat_bpb = &fat_bpbs[file->volume]; +#else + struct bpb* fat_bpb = &fat_bpbs[0]; +#endif + long clusternum=0, numclusters=0, sectornum=0, sector=0; + long cluster = file->firstcluster; + long i; + +#ifdef HAVE_FAT16SUPPORT + if (cluster < 0) /* FAT16 root dir */ + seeksector += fat_bpb->rootdiroffset; +#endif + + file->eof = false; + if (seeksector) { + /* we need to find the sector BEFORE the requested, since + the file struct stores the last accessed sector */ + seeksector--; + numclusters = clusternum = seeksector / fat_bpb->bpb_secperclus; + sectornum = seeksector % fat_bpb->bpb_secperclus; + + if (file->clusternum && clusternum >= file->clusternum) + { + cluster = file->lastcluster; + numclusters -= file->clusternum; + } + + for (i=0; ifirstcluster, seeksector, cluster, sector, sectornum); + + file->lastcluster = cluster; + file->lastsector = sector; + file->clusternum = clusternum; + file->sectornum = sectornum + 1; + return 0; +} + +int fat_opendir(IF_MV2(int volume,) + struct fat_dir *dir, unsigned long startcluster, + const struct fat_dir *parent_dir) +{ +#ifdef HAVE_MULTIVOLUME + struct bpb* fat_bpb = &fat_bpbs[volume]; + /* fixme: remove error check when done */ + if (volume >= NUM_VOLUMES || !fat_bpbs[volume].mounted) + { + LDEBUGF("fat_open() illegal volume %d\n", volume); + return -1; + } +#else + struct bpb* fat_bpb = &fat_bpbs[0]; +#endif + int rc; + + dir->entry = 0; + dir->sector = 0; + + if (startcluster == 0) + startcluster = fat_bpb->bpb_rootclus; + + rc = fat_open(IF_MV2(volume,) startcluster, &dir->file, parent_dir); + if(rc) + { + DEBUGF( "fat_opendir() - Couldn't open dir" + " (error code %d)\n", rc); + return rc * 10 - 1; + } + + return 0; +} + +/* Copies a segment of long file name (UTF-16 LE encoded) to the + * destination buffer (UTF-8 encoded). Copying is stopped when + * either 0x0000 or 0xffff (FAT pad char) is encountered. + * Trailing \0 is also appended at the end of the UTF8-encoded + * string. + * + * utf16src utf16 (little endian) segment to copy + * utf16count max number of the utf16-characters to copy + * utf8dst where to write UTF8-encoded string to + * + * returns the number of UTF-16 characters actually copied + */ +static int fat_copy_long_name_segment(unsigned char *utf16src, + int utf16count, unsigned char *utf8dst) { + int cnt = 0; + while ((utf16count--) > 0) { + unsigned short ucs = utf16src[0] | (utf16src[1] << 8); + if ((ucs == 0) || (ucs == FAT_LONGNAME_PAD_UCS)) { + break; + } + utf8dst = utf8encode(ucs, utf8dst); + utf16src += 2; + cnt++; + } + *utf8dst = 0; + return cnt; +} + +int fat_getnext(struct fat_dir *dir, struct fat_direntry *entry) +{ + bool done = false; + int i; + int rc; + unsigned char firstbyte; + /* Long file names are stored in special entries. Each entry holds + up to 13 characters. Names can be max 255 chars (not bytes!) long + hence max 20 entries are required. */ + int longarray[20]; + int longs=0; + int sectoridx=0; + unsigned char* cached_buf = dir->sectorcache[0]; + + dir->entrycount = 0; + + while(!done) + { + if ( !(dir->entry % DIR_ENTRIES_PER_SECTOR) || !dir->sector ) + { + rc = fat_readwrite(&dir->file, 1, cached_buf, false); + if (rc == 0) { + /* eof */ + entry->name[0] = 0; + break; + } + if (rc < 0) { + DEBUGF( "fat_getnext() - Couldn't read dir" + " (error code %d)\n", rc); + return rc * 10 - 1; + } + dir->sector = dir->file.lastsector; + } + + for (i = dir->entry % DIR_ENTRIES_PER_SECTOR; + i < DIR_ENTRIES_PER_SECTOR; i++) + { + unsigned int entrypos = i * DIR_ENTRY_SIZE; + + firstbyte = cached_buf[entrypos]; + dir->entry++; + + if (firstbyte == 0xe5) { + /* free entry */ + sectoridx = 0; + dir->entrycount = 0; + continue; + } + + if (firstbyte == 0) { + /* last entry */ + entry->name[0] = 0; + dir->entrycount = 0; + return 0; + } + + dir->entrycount++; + + /* longname entry? */ + if ( ( cached_buf[entrypos + FATDIR_ATTR] & + FAT_ATTR_LONG_NAME_MASK ) == FAT_ATTR_LONG_NAME ) { + longarray[longs++] = entrypos + sectoridx; + } + else { + if ( parse_direntry(entry, + &cached_buf[entrypos]) ) { + + /* don't return volume id entry */ + if ( (entry->attr & + (FAT_ATTR_VOLUME_ID|FAT_ATTR_DIRECTORY)) + == FAT_ATTR_VOLUME_ID) + continue; + + /* replace shortname with longname? */ + if ( longs ) { + int j; + /* This should be enough to hold any name segment utf8-encoded */ + unsigned char shortname[13]; /* 8+3+dot+\0 */ + unsigned char longname_utf8segm[6*4 + 1]; /* Add 1 for trailing \0 */ + int longname_utf8len = 0; + + strcpy(shortname, entry->name); /* Temporarily store it */ + entry->name[0] = 0; + + /* iterate backwards through the dir entries */ + for (j=longs-1; j>=0; j--) { + unsigned char* ptr = cached_buf; + int index = longarray[j]; + /* current or cached sector? */ + if ( sectoridx >= SECTOR_SIZE ) { + if ( sectoridx >= SECTOR_SIZE*2 ) { + if ( ( index >= SECTOR_SIZE ) && + ( index < SECTOR_SIZE*2 )) + ptr = dir->sectorcache[1]; + else + ptr = dir->sectorcache[2]; + } + else { + if ( index < SECTOR_SIZE ) + ptr = dir->sectorcache[1]; + } + + index &= SECTOR_SIZE-1; + } + + /* Try to append each segment of the long name. Check if we'd + exceed the buffer. Also check for FAT padding characters 0xFFFF. */ + if (fat_copy_long_name_segment(ptr + index + 1, 5, + longname_utf8segm) == 0) break; + // logf("SG: %s, EN: %s", longname_utf8segm, entry->name); + longname_utf8len += strlen(longname_utf8segm); + if (longname_utf8len < FAT_FILENAME_BYTES) + strcat(entry->name, longname_utf8segm); + else + break; + + if (fat_copy_long_name_segment(ptr + index + 14, 6, + longname_utf8segm) == 0) break; + // logf("SG: %s, EN: %s", longname_utf8segm, entry->name); + longname_utf8len += strlen(longname_utf8segm); + if (longname_utf8len < FAT_FILENAME_BYTES) + strcat(entry->name, longname_utf8segm); + else + break; + + if (fat_copy_long_name_segment(ptr + index + 28, 2, + longname_utf8segm) == 0) break; + // logf("SG: %s, EN: %s", longname_utf8segm, entry->name); + longname_utf8len += strlen(longname_utf8segm); + if (longname_utf8len < FAT_FILENAME_BYTES) + strcat(entry->name, longname_utf8segm); + else + break; + } + + /* Does the utf8-encoded name fit into the entry? */ + if (longname_utf8len >= FAT_FILENAME_BYTES) { + /* Take the short DOS name. Need to utf8-encode it since + it may contain chars from the upper half of the OEM + code page which wouldn't be a valid utf8. Beware: this + file will be shown with strange glyphs in file browser + since unicode 0x80 to 0x9F are control characters. */ + logf("SN-DOS: %s", shortname); + unsigned char *utf8; + utf8 = iso_decode(shortname, entry->name, -1, strlen(shortname)); + *utf8 = 0; + logf("SN: %s", entry->name); + } else { + // logf("LN: %s", entry->name); + // logf("LNLen: %d (%c)", longname_utf8len, entry->name[0]); + } + } + done = true; + sectoridx = 0; + i++; + break; + } + } + } + + /* save this sector, for longname use */ + if ( sectoridx ) + memcpy( dir->sectorcache[2], dir->sectorcache[0], SECTOR_SIZE ); + else + memcpy( dir->sectorcache[1], dir->sectorcache[0], SECTOR_SIZE ); + sectoridx += SECTOR_SIZE; + + } + return 0; +} + +unsigned int fat_get_cluster_size(IF_MV_NONVOID(int volume)) +{ +#ifndef HAVE_MULTIVOLUME + const int volume = 0; +#endif + struct bpb* fat_bpb = &fat_bpbs[volume]; + return fat_bpb->bpb_secperclus * SECTOR_SIZE; +} + +#ifdef HAVE_MULTIVOLUME +bool fat_ismounted(int volume) +{ + return (volume ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: dir.c,v 1.31 2006-06-30 05:43:08 amiconn Exp $ + * + * Copyright (C) 2002 by Björn Stenberg + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include +#include +#include +#include +#include "fat.h" +#include "dir.h" +/* +#include "debug.h" +#include "atoi.h" +#include "dircache.h" +*/ +#include "flashimgtool.h" + +#define MAX_OPEN_DIRS 8 + +static DIR opendirs[MAX_OPEN_DIRS]; + +#ifdef HAVE_MULTIVOLUME + +/* how to name volumes, first char must be outside of legal file names, + a number gets appended to enumerate, if applicable */ +#ifdef HAVE_MMC +static const char* vol_names = ""; +#define VOL_ENUM_POS 4 /* position of %d, to avoid runtime calculation */ +#else +static const char* vol_names = ""; +#define VOL_ENUM_POS 3 +#endif + +/* returns on which volume this is, and copies the reduced name + (sortof a preprocessor for volume-decorated pathnames) */ +static int strip_volume(const char* name, char* namecopy) +{ + int volume = 0; + const char *temp = name; + + while (*temp == '/') /* skip all leading slashes */ + ++temp; + + if (*temp && !strncmp(temp, vol_names, VOL_ENUM_POS)) + { + temp += VOL_ENUM_POS; /* behind special name */ + volume = atoi(temp); /* number is following */ + temp = strchr(temp, '/'); /* search for slash behind */ + if (temp != NULL) + name = temp; /* use the part behind the volume */ + else + name = "/"; /* else this must be the root dir */ + } + + strncpy(namecopy, name, MAX_PATH); + namecopy[MAX_PATH-1] = '\0'; + + return volume; +} +#endif /* #ifdef HAVE_MULTIVOLUME */ + + +#ifdef HAVE_HOTSWAP +// release all dir handles on a given volume "by force", to avoid leaks +int release_dirs(int volume) +{ + DIR* pdir = opendirs; + int dd; + int closed = 0; + for ( dd=0; ddfatdir.file.volume == volume) + { + pdir->busy = false; /* mark as available, no further action */ + closed++; + } + } + return closed; /* return how many we did */ +} +#endif /* #ifdef HAVE_HOTSWAP */ + +DIR* opendir(const char* name) +{ + char namecopy[MAX_PATH]; + char* part; + char* end; + struct fat_direntry entry; + int dd; + DIR* pdir = opendirs; +#ifdef HAVE_MULTIVOLUME + int volume; +#endif + + if ( name[0] != '/' ) { + DEBUGF("Only absolute paths supported right now\n"); + return NULL; + } + + /* find a free dir descriptor */ + for ( dd=0; ddbusy ) + break; + + if ( dd == MAX_OPEN_DIRS ) { + DEBUGF("Too many dirs open\n"); + errno = EMFILE; + return NULL; + } + + pdir->busy = true; + +#ifdef HAVE_MULTIVOLUME + /* try to extract a heading volume name, if present */ + volume = strip_volume(name, namecopy); + pdir->volumecounter = 0; +#else + strncpy(namecopy,name,sizeof(namecopy)); /* just copy */ + namecopy[sizeof(namecopy)-1] = '\0'; +#endif + + if ( fat_opendir(IF_MV2(volume,) &pdir->fatdir, 0, NULL) < 0 ) { + DEBUGF("Failed opening root dir\n"); + pdir->busy = false; + return NULL; + } + + for ( part = strtok_r(namecopy, "/", &end); part; + part = strtok_r(NULL, "/", &end)) { + /* scan dir for name */ + while (1) { + if ((fat_getnext(&pdir->fatdir,&entry) < 0) || + (!entry.name[0])) { + pdir->busy = false; + return NULL; + } + if ( (entry.attr & FAT_ATTR_DIRECTORY) && + (!strcasecmp(part, entry.name)) ) { + pdir->parent_dir = pdir->fatdir; + if ( fat_opendir(IF_MV2(volume,) + &pdir->fatdir, + entry.firstcluster, + &pdir->parent_dir) < 0 ) { + DEBUGF("Failed opening dir '%s' (%ld)\n", + part, entry.firstcluster); + pdir->busy = false; + return NULL; + } +#ifdef HAVE_MULTIVOLUME + pdir->volumecounter = -1; /* n.a. to subdirs */ +#endif + break; + } + } + } + + return pdir; +} + +int closedir(DIR* dir) +{ + dir->busy=false; + return 0; +} + +struct dirent* readdir(DIR* dir) +{ + struct fat_direntry entry; + struct dirent* theent = &(dir->theent); + + if (!dir->busy) + return NULL; + +#ifdef HAVE_MULTIVOLUME + /* Volumes (secondary file systems) get inserted into the root directory + of the first volume, since we have no separate top level. */ + if (dir->volumecounter >= 0 /* on a root dir */ + && dir->volumecounter < NUM_VOLUMES /* in range */ + && dir->fatdir.file.volume == 0) /* at volume 0 */ + { /* fake special directories, which don't really exist, but + will get redirected upon opendir() */ + while (++dir->volumecounter < NUM_VOLUMES) + { + if (fat_ismounted(dir->volumecounter)) + { + memset(theent, 0, sizeof(*theent)); + theent->attribute = FAT_ATTR_DIRECTORY | FAT_ATTR_VOLUME; + snprintf(theent->d_name, sizeof(theent->d_name), + vol_names, dir->volumecounter); + return theent; + } + } + } +#endif + /* normal directory entry fetching follows here */ + if (fat_getnext(&(dir->fatdir),&entry) < 0) + return NULL; + + if ( !entry.name[0] ) + return NULL; + + strncpy(theent->d_name, entry.name, sizeof( theent->d_name ) ); + theent->attribute = entry.attr; + theent->size = entry.filesize; + theent->startcluster = entry.firstcluster; + theent->wrtdate = entry.wrtdate; + theent->wrttime = entry.wrttime; + + return theent; +} + +int mkdir(const char *name, int mode) +{ + DIR *dir; + char namecopy[MAX_PATH]; + char* end; + char *basename; + char *parent; + struct dirent *entry; + struct fat_dir newdir; + int rc; + + (void)mode; + + if ( name[0] != '/' ) { + DEBUGF("mkdir: Only absolute paths supported right now\n"); + return -1; + } + + strncpy(namecopy,name,sizeof(namecopy)); + namecopy[sizeof(namecopy)-1] = 0; + + /* Split the base name and the path */ + end = strrchr(namecopy, '/'); + *end = 0; + basename = end+1; + + if(namecopy == end) /* Root dir? */ + parent = "/"; + else + parent = namecopy; + + DEBUGF("mkdir: parent: %s, name: %s\n", parent, basename); + + dir = opendir(parent); + + if(!dir) { + DEBUGF("mkdir: can't open parent dir\n"); + return -2; + } + + if(basename[0] == 0) { + DEBUGF("mkdir: Empty dir name\n"); + errno = EINVAL; + return -3; + } + + /* Now check if the name already exists */ + while ((entry = readdir(dir))) { + if ( !strcasecmp(basename, entry->d_name) ) { + DEBUGF("mkdir error: file exists\n"); + errno = EEXIST; + closedir(dir); + return - 4; + } + } + + memset(&newdir, sizeof(struct fat_dir), 0); + + rc = fat_create_dir(basename, &newdir, &(dir->fatdir)); +#ifdef HAVE_DIRCACHE + if (rc >= 0) + dircache_mkdir(name); +#endif + + closedir(dir); + + return rc; +} + +int rmdir(const char* name) +{ + int rc; + DIR* dir; + struct dirent* entry; + + dir = opendir(name); + if (!dir) + { + errno = ENOENT; /* open error */ + return -1; + } + + /* check if the directory is empty */ + while ((entry = readdir(dir))) + { + if (strcmp(entry->d_name, ".") && + strcmp(entry->d_name, "..")) + { + DEBUGF("rmdir error: not empty\n"); + errno = ENOTEMPTY; + closedir(dir); + return -2; + } + } + + rc = fat_remove(&(dir->fatdir.file)); + if ( rc < 0 ) { + DEBUGF("Failed removing dir: %d\n", rc); + errno = EIO; + rc = rc * 10 - 3; + } +#ifdef HAVE_DIRCACHE + else + { + dircache_rmdir(name); + } +#endif + + closedir(dir); + + return rc; +} Index: utils/emuriver/src/flashimgtool/rbunicode.h =================================================================== --- utils/emuriver/src/flashimgtool/rbunicode.h (revision 0) +++ utils/emuriver/src/flashimgtool/rbunicode.h (revision 0) @@ -0,0 +1,28 @@ +/* Some conversion functions for handling UTF-8 + * + * copyright Marcoen Hirschberg (2004,2005) + * + * I got all the info from: + * http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + * and + * http://en.wikipedia.org/wiki/Unicode + */ + +#define CODEPAGE_DIR "/.rockbox/codepages" + +#define MAX_CP_TABLE_SIZE 32768 + +#define MASK 0xC0 /* 11000000 */ +#define COMP 0x80 /* 10x */ + + +/* Encode a UCS value as UTF-8 and return a pointer after this UTF-8 char. */ +unsigned char* utf8encode(unsigned long ucs, unsigned char *utf8); +unsigned char* iso_decode(const unsigned char *latin1, unsigned char *utf8, int cp, int count); +unsigned char* utf16LEdecode(const unsigned char *utf16, unsigned char *utf8, int count); +unsigned char* utf16BEdecode(const unsigned char *utf16, unsigned char *utf8, int count); +unsigned char* utf16decode(const unsigned char *utf16, unsigned char *utf8, unsigned int count); +unsigned long utf8length(const unsigned char *utf8); +const unsigned char* utf8decode(const unsigned char *utf8, unsigned short *ucs); +void set_codepage(int cp); +int utf8seek(const unsigned char* utf8, int offset); Index: utils/emuriver/src/flashimgtool/fat.h =================================================================== --- utils/emuriver/src/flashimgtool/fat.h (revision 0) +++ utils/emuriver/src/flashimgtool/fat.h (revision 0) @@ -0,0 +1,119 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: fat.h,v 1.14 2006-07-31 22:59:45 raenye Exp $ + * + * Copyright (C) 2002 by Linus Nielsen Feltzing + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef FAT_H +#define FAT_H + +#include +#include "ata.h" /* for volume definitions */ + +#define SECTOR_SIZE 512 + +/* Number of bytes reserved for a file name (including the trailing \0). + Since names are stored in the entry as UTF-8, we won't be able to + store all names allowed by FAT. In FAT, a name can have max 255 + characters (not bytes!). Since the UTF-8 encoding of a char may take + up to 4 bytes, there will be names that we won't be able to store + completely. For such names, the short DOS name is used. */ +#define FAT_FILENAME_BYTES 256 + +struct fat_direntry +{ + unsigned char name[FAT_FILENAME_BYTES]; /* UTF-8 encoded name plus \0 */ + unsigned short attr; /* Attributes */ + unsigned char crttimetenth; /* Millisecond creation + time stamp (0-199) */ + unsigned short crttime; /* Creation time */ + unsigned short crtdate; /* Creation date */ + unsigned short lstaccdate; /* Last access date */ + unsigned short wrttime; /* Last write time */ + unsigned short wrtdate; /* Last write date */ + unsigned long filesize; /* File size in bytes */ + long firstcluster; /* fstclusterhi<<16 + fstcluslo */ +}; + +#define FAT_ATTR_READ_ONLY 0x01 +#define FAT_ATTR_HIDDEN 0x02 +#define FAT_ATTR_SYSTEM 0x04 +#define FAT_ATTR_VOLUME_ID 0x08 +#define FAT_ATTR_DIRECTORY 0x10 +#define FAT_ATTR_ARCHIVE 0x20 +#define FAT_ATTR_VOLUME 0x40 /* this is a volume, not a real directory */ + +struct fat_file +{ + long firstcluster; /* first cluster in file */ + long lastcluster; /* cluster of last access */ + long lastsector; /* sector of last access */ + long clusternum; /* current clusternum */ + long sectornum; /* sector number in this cluster */ + unsigned int direntry; /* short dir entry index from start of dir */ + unsigned int direntries; /* number of dir entries used by this file */ + long dircluster; /* first cluster of dir */ + bool eof; +#ifdef HAVE_MULTIVOLUME + int volume; /* file resides on which volume */ +#endif +}; + +struct fat_dir +{ + unsigned int entry; + unsigned int entrycount; + long sector; + struct fat_file file; + unsigned char sectorcache[3][SECTOR_SIZE]; +}; + + +extern void fat_init(void); +extern int fat_mount(IF_MV2(int volume,) IF_MV2(int drive,) long startsector); +extern int fat_unmount(int volume, bool flush); +extern void fat_size(IF_MV2(int volume,) unsigned long* size, unsigned long* free); // public for info +extern void fat_recalc_free(IF_MV_NONVOID(int volume)); // public for debug info screen +extern int fat_create_dir(const char* name, + struct fat_dir* newdir, + struct fat_dir* dir); +extern long fat_startsector(IF_MV_NONVOID(int volume)); // public for config sector +extern int fat_open(IF_MV2(int volume,) + long cluster, + struct fat_file* ent, + const struct fat_dir* dir); +extern int fat_create_file(const char* name, + struct fat_file* ent, + struct fat_dir* dir); +extern long fat_readwrite(struct fat_file *ent, long sectorcount, + void* buf, bool write ); +extern int fat_closewrite(struct fat_file *ent, long size, int attr); +extern int fat_seek(struct fat_file *ent, unsigned long sector ); +extern int fat_remove(struct fat_file *ent); +extern int fat_truncate(const struct fat_file *ent); +extern int fat_rename(struct fat_file* file, + struct fat_dir* dir, + const unsigned char* newname, + long size, int attr); + +extern int fat_opendir(IF_MV2(int volume,) + struct fat_dir *ent, unsigned long currdir, + const struct fat_dir *parent_dir); +extern int fat_getnext(struct fat_dir *ent, struct fat_direntry *entry); +extern unsigned int fat_get_cluster_size(IF_MV_NONVOID(int volume)); +extern bool fat_ismounted(int volume); + +#endif Index: utils/emuriver/src/flashimgtool/file.c =================================================================== --- utils/emuriver/src/flashimgtool/file.c (revision 0) +++ utils/emuriver/src/flashimgtool/file.c (revision 0) @@ -0,0 +1,749 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: file.c,v 1.72 2006-05-16 06:53:41 hardeeps Exp $ + * + * Copyright (C) 2002 by Björn Stenberg + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include +#include +#include +#include "file.h" +#include "fat.h" +#include "dir.h" +/* +#include "debug.h" +#include "dircache.h" +#include "system.h" +*/ +#include "flashimgtool.h" + +/* + These functions provide a roughly POSIX-compatible file IO API. + + Since the fat32 driver only manages sectors, we maintain a one-sector + cache for each open file. This way we can provide byte access without + having to re-read the sector each time. + The penalty is the RAM used for the cache and slightly more complex code. +*/ + +struct filedesc { + unsigned char cache[SECTOR_SIZE]; + int cacheoffset; /* invariant: 0 <= cacheoffset <= SECTOR_SIZE */ + long fileoffset; + long size; + int attr; + struct fat_file fatfile; + bool busy; + bool write; + bool dirty; + bool trunc; +}; + +static struct filedesc openfiles[MAX_OPEN_FILES]; + +static int flush_cache(int fd); + +int creat(const char *pathname, mode_t mode) +{ + (void)mode; + return open(pathname, O_WRONLY|O_CREAT|O_TRUNC); +} + +static int open_internal(const char* pathname, int flags, bool use_cache) +{ + DIR* dir; + struct dirent* entry; + int fd; + char pathnamecopy[MAX_PATH]; + char* name; + struct filedesc* file = NULL; + int rc; +#ifndef HAVE_DIRCACHE + (void)use_cache; +#endif + + LDEBUGF("open(\"%s\",%d)\n",pathname,flags); + + if ( pathname[0] != '/' ) { + DEBUGF("'%s' is not an absolute path.\n",pathname); + DEBUGF("Only absolute pathnames supported at the moment\n"); + errno = EINVAL; + return -1; + } + + /* find a free file descriptor */ + for ( fd=0; fdwrite = true; + + if (flags & O_TRUNC) + file->trunc = true; + } + file->busy = true; + +#ifdef HAVE_DIRCACHE + if (dircache_is_enabled() && !file->write && use_cache) + { + const struct dircache_entry *ce; + + ce = dircache_get_entry_ptr(pathname); + if (!ce) + { + errno = ENOENT; + file->busy = false; + return -7; + } + + fat_open(IF_MV2(unsupported at the moment,) + ce->startcluster, + &(file->fatfile), + NULL); + file->size = ce->size; + file->attr = ce->attribute; + file->cacheoffset = -1; + file->fileoffset = 0; + + return fd; + } +#endif + + strncpy(pathnamecopy,pathname,sizeof(pathnamecopy)); + pathnamecopy[sizeof(pathnamecopy)-1] = 0; + + /* locate filename */ + name=strrchr(pathnamecopy+1,'/'); + if ( name ) { + *name = 0; + dir = opendir(pathnamecopy); + *name = '/'; + name++; + } + else { + dir = opendir("/"); + name = pathnamecopy+1; + } + if (!dir) { + DEBUGF("Failed opening dir\n"); + errno = EIO; + file->busy = false; + return -4; + } + + if(name[0] == 0) { + DEBUGF("Empty file name\n"); + errno = EINVAL; + file->busy = false; + closedir(dir); + return -5; + } + + /* scan dir for name */ + while ((entry = readdir(dir))) { + if ( !strcasecmp(name, entry->d_name) ) { + fat_open(IF_MV2(dir->fatdir.file.volume,) + entry->startcluster, + &(file->fatfile), + &(dir->fatdir)); + file->size = file->trunc ? 0 : entry->size; + file->attr = entry->attribute; + break; + } + } + + if ( !entry ) { + LDEBUGF("Didn't find file %s\n",name); + if ( file->write && (flags & O_CREAT) ) { + rc = fat_create_file(name, + &(file->fatfile), + &(dir->fatdir)); + if (rc < 0) { + DEBUGF("Couldn't create %s in %s\n",name,pathnamecopy); + errno = EIO; + file->busy = false; + closedir(dir); + return rc * 10 - 6; + } +#ifdef HAVE_DIRCACHE + dircache_add_file(pathname, file->fatfile.firstcluster); +#endif + file->size = 0; + file->attr = 0; + } + else { + DEBUGF("Couldn't find %s in %s\n",name,pathnamecopy); + errno = ENOENT; + file->busy = false; + closedir(dir); + return -7; + } + } else { + if(file->write && (file->attr & FAT_ATTR_DIRECTORY)) { + errno = EISDIR; + file->busy = false; + closedir(dir); + return -8; + } + } + closedir(dir); + + file->cacheoffset = -1; + file->fileoffset = 0; + + if (file->write && (flags & O_APPEND)) { + rc = lseek(fd,0,SEEK_END); + if (rc < 0 ) + return rc * 10 - 9; + } + +#ifdef HAVE_DIRCACHE + if (file->write) + dircache_bind(fd, pathname); +#endif + + return fd; +} + +int open(const char* pathname, int flags) +{ + /* By default, use the dircache if available. */ + return open_internal(pathname, flags, true); +} + +int close(int fd) +{ + struct filedesc* file = &openfiles[fd]; + int rc = 0; + + LDEBUGF("close(%d)\n", fd); + + if (fd < 0 || fd > MAX_OPEN_FILES-1) { + errno = EINVAL; + return -1; + } + if (!file->busy) { + errno = EBADF; + return -2; + } + if (file->write) { + rc = fsync(fd); + if (rc < 0) + return rc * 10 - 3; +#ifdef HAVE_DIRCACHE + dircache_update_filesize(fd, file->size, file->fatfile.firstcluster); +#endif + } + + file->busy = false; + return 0; +} + +int fsync(int fd) +{ + struct filedesc* file = &openfiles[fd]; + int rc = 0; + + LDEBUGF("fsync(%d)\n", fd); + + if (fd < 0 || fd > MAX_OPEN_FILES-1) { + errno = EINVAL; + return -1; + } + if (!file->busy) { + errno = EBADF; + return -2; + } + if (file->write) { + /* flush sector cache */ + if ( file->dirty ) { + rc = flush_cache(fd); + if (rc < 0) + return rc * 10 - 3; + } + + /* truncate? */ + if (file->trunc) { + rc = ftruncate(fd, file->size); + if (rc < 0) + return rc * 10 - 4; + } + + /* tie up all loose ends */ + rc = fat_closewrite(&(file->fatfile), file->size, file->attr); + if (rc < 0) + return rc * 10 - 5; + } + return 0; +} + +int remove(const char* name) +{ + int rc; + struct filedesc* file; + /* Can't use dircache now, because we need to access the fat structures. */ + int fd = open_internal(name, O_WRONLY, false); + if ( fd < 0 ) + return fd * 10 - 1; + + file = &openfiles[fd]; +#ifdef HAVE_DIRCACHE + dircache_remove(name); +#endif + rc = fat_remove(&(file->fatfile)); + if ( rc < 0 ) { + DEBUGF("Failed removing file: %d\n", rc); + errno = EIO; + return rc * 10 - 3; + } + + file->size = 0; + + rc = close(fd); + if (rc<0) + return rc * 10 - 4; + + return 0; +} + +int rename(const char* path, const char* newpath) +{ + int rc, fd; + DIR* dir; + char* nameptr; + char* dirptr; + struct filedesc* file; + char newpath2[MAX_PATH]; + + /* verify new path does not already exist */ + /* If it is a directory, errno == EISDIR if the name exists */ + fd = open(newpath, O_RDONLY); + if ( fd >= 0 || errno == EISDIR) { + close(fd); + errno = EBUSY; + return -1; + } + close(fd); + + fd = open_internal(path, O_RDONLY, false); + if ( fd < 0 ) { + errno = EIO; + return fd * 10 - 2; + } + + /* extract new file name */ + nameptr = strrchr(newpath,'/'); + if (nameptr) + nameptr++; + else + return - 3; + + /* Extract new path */ + strcpy(newpath2, newpath); + + dirptr = strrchr(newpath2,'/'); + if(dirptr) + *dirptr = 0; + else + return - 4; + + dirptr = newpath2; + + if(strlen(dirptr) == 0) { + dirptr = "/"; + } + + dir = opendir(dirptr); + if(!dir) + return - 5; + + file = &openfiles[fd]; +#ifdef HAVE_DIRCACHE + dircache_rename(path, newpath); +#endif + + rc = fat_rename(&file->fatfile, &dir->fatdir, nameptr, + file->size, file->attr); +#ifdef HAVE_MULTIVOLUME + if ( rc == -1) { + DEBUGF("Failed renaming file across volumnes: %d\n", rc); + errno = EXDEV; + return -6; + } +#endif + if ( rc < 0 ) { + DEBUGF("Failed renaming file: %d\n", rc); + errno = EIO; + return rc * 10 - 7; + } + + rc = close(fd); + if (rc<0) { + errno = EIO; + return rc * 10 - 8; + } + + rc = closedir(dir); + if (rc<0) { + errno = EIO; + return rc * 10 - 9; + } + + return 0; +} + +int ftruncate(int fd, off_t size) +{ + int rc, sector; + struct filedesc* file = &openfiles[fd]; + + sector = size / SECTOR_SIZE; + if (size % SECTOR_SIZE) + sector++; + + rc = fat_seek(&(file->fatfile), sector); + if (rc < 0) { + errno = EIO; + return rc * 10 - 1; + } + + rc = fat_truncate(&(file->fatfile)); + if (rc < 0) { + errno = EIO; + return rc * 10 - 2; + } + + file->size = size; +#ifdef HAVE_DIRCACHE + dircache_update_filesize(fd, size, file->fatfile.firstcluster); +#endif + + return 0; +} + +static int flush_cache(int fd) +{ + int rc; + struct filedesc* file = &openfiles[fd]; + long sector = file->fileoffset / SECTOR_SIZE; + + DEBUGF("Flushing dirty sector cache\n"); + + /* make sure we are on correct sector */ + rc = fat_seek(&(file->fatfile), sector); + if ( rc < 0 ) + return rc * 10 - 3; + + rc = fat_readwrite(&(file->fatfile), 1, + file->cache, true ); + + if ( rc < 0 ) { + if(file->fatfile.eof) + errno = ENOSPC; + + return rc * 10 - 2; + } + + file->dirty = false; + + return 0; +} + +static int readwrite(int fd, void* buf, long count, bool write) +{ + long sectors; + long nread=0; + struct filedesc* file = &openfiles[fd]; + int rc; + + if ( !file->busy ) { + errno = EBADF; + return -1; + } + + LDEBUGF( "readwrite(%d,%lx,%ld,%s)\n", + fd,(long)buf,count,write?"write":"read"); + + /* attempt to read past EOF? */ + if (!write && count > file->size - file->fileoffset) + count = file->size - file->fileoffset; + + /* any head bytes? */ + if ( file->cacheoffset != -1 ) { + int offs = file->cacheoffset; + int headbytes = MIN(count, SECTOR_SIZE - offs); + + if (write) { + memcpy( file->cache + offs, buf, headbytes ); + file->dirty = true; + } + else { + memcpy( buf, file->cache + offs, headbytes ); + } + + if (offs + headbytes == SECTOR_SIZE) { + if (file->dirty) { + int rc = flush_cache(fd); + if ( rc < 0 ) { + errno = EIO; + return rc * 10 - 2; + } + } + file->cacheoffset = -1; + } + else { + file->cacheoffset += headbytes; + } + + nread = headbytes; + count -= headbytes; + } + + /* If the buffer has been modified, either it has been flushed already + * (if (offs+headbytes == SECTOR_SIZE)...) or does not need to be (no + * more data to follow in this call). Do NOT flush here. */ + + /* read/write whole sectors right into/from the supplied buffer */ + sectors = count / SECTOR_SIZE; + if ( sectors ) { + int rc = fat_readwrite(&(file->fatfile), sectors, + (unsigned char*)buf+nread, write ); + if ( rc < 0 ) { + DEBUGF("Failed read/writing %ld sectors\n",sectors); + errno = EIO; + if(write && file->fatfile.eof) { + DEBUGF("No space left on device\n"); + errno = ENOSPC; + } else { + file->fileoffset += nread; + } + file->cacheoffset = -1; + return nread ? nread : rc * 10 - 4; + } + else { + if ( rc > 0 ) { + nread += rc * SECTOR_SIZE; + count -= sectors * SECTOR_SIZE; + + /* if eof, skip tail bytes */ + if ( rc < sectors ) + count = 0; + } + else { + /* eof */ + count=0; + } + + file->cacheoffset = -1; + } + } + + /* any tail bytes? */ + if ( count ) { + if (write) { + if ( file->fileoffset + nread < file->size ) { + /* sector is only partially filled. copy-back from disk */ + int rc; + LDEBUGF("Copy-back tail cache\n"); + rc = fat_readwrite(&(file->fatfile), 1, file->cache, false ); + if ( rc < 0 ) { + DEBUGF("Failed writing\n"); + errno = EIO; + file->fileoffset += nread; + file->cacheoffset = -1; + return nread ? nread : rc * 10 - 5; + } + /* seek back one sector to put file position right */ + rc = fat_seek(&(file->fatfile), + (file->fileoffset + nread) / + SECTOR_SIZE); + if ( rc < 0 ) { + DEBUGF("fat_seek() failed\n"); + errno = EIO; + file->fileoffset += nread; + file->cacheoffset = -1; + return nread ? nread : rc * 10 - 6; + } + } + memcpy( file->cache, (unsigned char*)buf + nread, count ); + file->dirty = true; + } + else { + rc = fat_readwrite(&(file->fatfile), 1, &(file->cache),false); + if (rc < 1 ) { + DEBUGF("Failed caching sector\n"); + errno = EIO; + file->fileoffset += nread; + file->cacheoffset = -1; + return nread ? nread : rc * 10 - 7; + } + memcpy( (unsigned char*)buf + nread, file->cache, count ); + } + + nread += count; + file->cacheoffset = count; + } + + file->fileoffset += nread; + LDEBUGF("fileoffset: %ld\n", file->fileoffset); + + /* adjust file size to length written */ + if ( write && file->fileoffset > file->size ) + { + file->size = file->fileoffset; +#ifdef HAVE_DIRCACHE + dircache_update_filesize(fd, file->size, file->fatfile.firstcluster); +#endif + } + + return nread; +} + +ssize_t write(int fd, const void* buf, size_t count) +{ + if (!openfiles[fd].write) { + errno = EACCES; + return -1; + } + return readwrite(fd, (void *)buf, count, true); +} + +ssize_t read(int fd, void* buf, size_t count) +{ + return readwrite(fd, buf, count, false); +} + + +off_t lseek(int fd, off_t offset, int whence) +{ + off_t pos; + long newsector; + long oldsector; + int sectoroffset; + int rc; + struct filedesc* file = &openfiles[fd]; + + LDEBUGF("lseek(%d,%ld,%d)\n",fd,offset,whence); + + if ( !file->busy ) { + errno = EBADF; + return -1; + } + + switch ( whence ) { + case SEEK_SET: + pos = offset; + break; + + case SEEK_CUR: + pos = file->fileoffset + offset; + break; + + case SEEK_END: + pos = file->size + offset; + break; + + default: + errno = EINVAL; + return -2; + } + if ((pos < 0) || (pos > file->size)) { + errno = EINVAL; + return -3; + } + + /* new sector? */ + newsector = pos / SECTOR_SIZE; + oldsector = file->fileoffset / SECTOR_SIZE; + sectoroffset = pos % SECTOR_SIZE; + + if ( (newsector != oldsector) || + ((file->cacheoffset==-1) && sectoroffset) ) { + + if ( newsector != oldsector ) { + if (file->dirty) { + rc = flush_cache(fd); + if (rc < 0) + return rc * 10 - 5; + } + + rc = fat_seek(&(file->fatfile), newsector); + if ( rc < 0 ) { + errno = EIO; + return rc * 10 - 4; + } + } + if ( sectoroffset ) { + rc = fat_readwrite(&(file->fatfile), 1, + &(file->cache),false); + if ( rc < 0 ) { + errno = EIO; + return rc * 10 - 6; + } + file->cacheoffset = sectoroffset; + } + else + file->cacheoffset = -1; + } + else + if ( file->cacheoffset != -1 ) + file->cacheoffset = sectoroffset; + + file->fileoffset = pos; + + return pos; +} + +off_t filesize(int fd) +{ + struct filedesc* file = &openfiles[fd]; + + if ( !file->busy ) { + errno = EBADF; + return -1; + } + + return file->size; +} + + +#ifdef HAVE_HOTSWAP +// release all file handles on a given volume "by force", to avoid leaks +int release_files(int volume) +{ + struct filedesc* pfile = openfiles; + int fd; + int closed = 0; + for ( fd=0; fdfatfile.volume == volume) + { + pfile->busy = false; /* mark as available, no further action */ + closed++; + } + } + return closed; /* return how many we did */ +} +#endif /* #ifdef HAVE_HOTSWAP */ Index: utils/emuriver/src/flashimgtool/dir.h =================================================================== --- utils/emuriver/src/flashimgtool/dir.h (revision 0) +++ utils/emuriver/src/flashimgtool/dir.h (revision 0) @@ -0,0 +1,87 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: dir.h,v 1.12 2005-02-26 21:18:05 jyp Exp $ + * + * Copyright (C) 2002 by Björn Stenberg + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#ifndef _DIR_H_ +#define _DIR_H_ + +#include +#include + +#define ATTR_READ_ONLY 0x01 +#define ATTR_HIDDEN 0x02 +#define ATTR_SYSTEM 0x04 +#define ATTR_VOLUME_ID 0x08 +#define ATTR_DIRECTORY 0x10 +#define ATTR_ARCHIVE 0x20 +#define ATTR_VOLUME 0x40 /* this is a volume, not a real directory */ + +#ifdef SIMULATOR +#define dirent sim_dirent +#define DIR SIM_DIR +#define opendir(x) sim_opendir(x) +#define readdir(x) sim_readdir(x) +#define closedir(x) sim_closedir(x) +#define mkdir(x, y) sim_mkdir(x, y) +#define rmdir(x) sim_rmdir(x) +#endif + +#ifndef DIRENT_DEFINED + +struct dirent { + unsigned char d_name[MAX_PATH]; + int attribute; + long size; + long startcluster; + unsigned short wrtdate; /* Last write date */ + unsigned short wrttime; /* Last write time */ +}; +#endif + +#include "fat.h" + +typedef struct { +#ifndef SIMULATOR + bool busy; + long startcluster; + struct fat_dir fatdir; + struct fat_dir parent_dir; + struct dirent theent; +#ifdef HAVE_MULTIVOLUME + int volumecounter; /* running counter for faked volume entries */ +#endif +#else + /* simulator: */ + void *dir; /* actually a DIR* dir */ + char *name; +#endif +} DIR; + +#ifndef DIRFUNCTIONS_DEFINED + +extern DIR* opendir(const char* name); +extern int closedir(DIR* dir); +extern int mkdir(const char* name, int mode); +extern int rmdir(const char* name); + +extern struct dirent* readdir(DIR* dir); + +extern int release_dirs(int volume); + +#endif /* DIRFUNCTIONS_DEFINED */ + +#endif Index: utils/emuriver/src/flashimgtool/file.h =================================================================== --- utils/emuriver/src/flashimgtool/file.h (revision 0) +++ utils/emuriver/src/flashimgtool/file.h (revision 0) @@ -0,0 +1,80 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: file.h,v 1.15 2005-10-07 17:38:05 miipekk Exp $ + * + * Copyright (C) 2002 by Björn Stenberg + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef _FILE_H_ +#define _FILE_H_ + +#include + +#undef MAX_PATH /* this avoids problems when building simulator */ +#define MAX_PATH 260 + +#define MAX_OPEN_FILES 8 + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif +#ifndef SEEK_CUR +#define SEEK_CUR 1 +#endif +#ifndef SEEK_END +#define SEEK_END 2 +#endif + +#ifndef O_RDONLY +#define O_RDONLY 0 +#define O_WRONLY 1 +#define O_RDWR 2 +#define O_CREAT 4 +#define O_APPEND 8 +#define O_TRUNC 0x10 +#endif + +#ifdef SIMULATOR +#define open(x,y) sim_open(x,y) +#define creat(x,y) sim_creat(x,y) +#define remove(x) sim_remove(x) +#define rename(x,y) sim_rename(x,y) +#define filesize(x) sim_filesize(x) +#define fsync(x) sim_fsync(x) +#define ftruncate(x,y) sim_ftruncate(x,y) +#define lseek(x,y,z) sim_lseek(x,y,z) +#endif + +typedef int (*open_func)(const char* pathname, int flags); +typedef ssize_t (*read_func)(int fd, void *buf, size_t count); +typedef int (*creat_func)(const char *pathname, mode_t mode); +typedef ssize_t (*write_func)(int fd, const void *buf, size_t count); +typedef void (*qsort_func)(void *base, size_t nmemb, size_t size, + int(*_compar)(const void *, const void *)); + +extern int open(const char* pathname, int flags); +extern int close(int fd); +extern int fsync(int fd); +extern ssize_t read(int fd, void *buf, size_t count); +extern off_t lseek(int fildes, off_t offset, int whence); +extern int creat(const char *pathname, mode_t mode); +extern ssize_t write(int fd, const void *buf, size_t count); +extern int remove(const char* pathname); +extern int rename(const char* path, const char* newname); +extern int ftruncate(int fd, off_t length); +extern off_t filesize(int fd); +extern int release_files(int volume); + +#endif Index: utils/emuriver/src/flashimgtool/unicode.c =================================================================== --- utils/emuriver/src/flashimgtool/unicode.c (revision 0) +++ utils/emuriver/src/flashimgtool/unicode.c (revision 0) @@ -0,0 +1,314 @@ +/* Some conversion functions for handling UTF-8 + * + * copyright Marcoen Hirschberg (2004,2005) + * + * I got all the info from: + * http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + * and + * http://en.wikipedia.org/wiki/Unicode + */ + +#include +#include "file.h" +/* +#include "debug.h" +*/ +#include "rbunicode.h" +#include "flashimgtool.h" + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +#define NUM_TABLES 5 +#define NUM_CODEPAGES 13 + +static int default_codepage = 0; +static unsigned short codepage_table[MAX_CP_TABLE_SIZE]; +static int loaded_cp_table = 0; + + +static const unsigned char utf8comp[6] = +{ + 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC +}; + +static const char *filename[NUM_TABLES] = +{ + CODEPAGE_DIR"/iso.cp", + CODEPAGE_DIR"/932.cp", /* SJIS */ + CODEPAGE_DIR"/936.cp", /* GB2312 */ + CODEPAGE_DIR"/949.cp", /* KSX1001 */ + CODEPAGE_DIR"/950.cp" /* BIG5 */ +}; + +static const char cp_2_table[NUM_CODEPAGES] = +{ + 0, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 5, 0 +}; + +/* Load codepage file into memory */ +int load_cp_table(int cp) +{ + int i=0; + int table = cp_2_table[cp]; + int file, tablesize; + unsigned char tmp[2]; + + if (table == 0 || table == loaded_cp_table) + return 1; + + file = open(filename[table-1], O_RDONLY|O_BINARY); + + if (file < 0) { + DEBUGF("Can't open codepage file: %s.cp\n", filename[table-1]); + return 0; + } + + tablesize = filesize(file) / 2; + + if (tablesize > MAX_CP_TABLE_SIZE) { + DEBUGF("Invalid codepage file: %s.cp\n", filename[table-1]); + close(file); + return 0; + } + + while (i < tablesize) { + if (!read(file, tmp, 2)) { + DEBUGF("Can't read from codepage file: %s.cp\n", + filename[table-1]); + loaded_cp_table = 0; + return 0; + } + codepage_table[i++] = (tmp[1] << 8) | tmp[0]; + } + + loaded_cp_table = table; + close(file); + return 1; +} + +/* Encode a UCS value as UTF-8 and return a pointer after this UTF-8 char. */ +unsigned char* utf8encode(unsigned long ucs, unsigned char *utf8) +{ + int tail = 0; + + if (ucs > 0x7F) + while (ucs >> (5*tail + 6)) + tail++; + + *utf8++ = (ucs >> (6*tail)) | utf8comp[tail]; + while (tail--) + *utf8++ = ((ucs >> (6*tail)) & (MASK ^ 0xFF)) | COMP; + + return utf8; +} + +/* Recode an iso encoded string to UTF-8 */ +unsigned char* iso_decode(const unsigned char *iso, unsigned char *utf8, + int cp, int count) +{ + unsigned short ucs, tmp; + + if (cp == -1) /* use default codepage */ + cp = default_codepage; + + if (!load_cp_table(cp)) cp = 0; + + while (count--) { + if (*iso < 128 || cp == 0x0C) /* Already UTF-8 */ + *utf8++ = *iso++; + + else { + + /* cp tells us which codepage to convert from */ + switch (cp) { + case 0x01: /* Greek (ISO-8859-7) */ + case 0x02: /* Hebrew (ISO-8859-8) */ + case 0x03: /* Cyrillic (CP1251) */ + case 0x04: /* Thai (ISO-8859-11) */ + case 0x05: /* Arabic (CP1256) */ + case 0x06: /* Turkish (ISO-8859-9) */ + case 0x07: /* Latin Extended (ISO-8859-2) */ + tmp = ((cp-1)*128) + (*iso++ - 128); + ucs = codepage_table[tmp]; + break; + + case 0x08: /* Japanese (SJIS) */ + if (*iso > 0xA0 && *iso < 0xE0) { + tmp = *iso++ | (0xA100 - 0x8000); + ucs = codepage_table[tmp]; + break; + } + + case 0x09: /* Simplified Chinese (GB2312) */ + case 0x0A: /* Korean (KSX1001) */ + case 0x0B: /* Traditional Chinese (BIG5) */ + if (count < 1 || !iso[1]) { + ucs = *iso++; + break; + } + + /* we assume all cjk strings are written + in big endian order */ + tmp = *iso++ << 8; + tmp |= *iso++; + tmp -= 0x8000; + ucs = codepage_table[tmp]; + count--; + break; + + default: + ucs = *iso++; + break; + } + + if (ucs == 0) /* unknown char, use replacement char */ + ucs = 0xfffd; + utf8 = utf8encode(ucs, utf8); + } + } + return utf8; +} + +/* Recode a UTF-16 string with little-endian byte ordering to UTF-8 */ +unsigned char* utf16LEdecode(const unsigned char *utf16, unsigned char *utf8, + int count) +{ + unsigned long ucs; + + while (count > 0) { + /* Check for a surrogate pair */ + if (utf16[1] >= 0xD8 && utf16[1] < 0xE0) { + ucs = 0x10000 + ((utf16[0] << 10) | ((utf16[1] - 0xD8) << 18) + | utf16[2] | ((utf16[3] - 0xDC) << 8)); + utf16 += 4; + count -= 2; + } else { + ucs = (utf16[0] | (utf16[1] << 8)); + utf16 += 2; + count -= 1; + } + utf8 = utf8encode(ucs, utf8); + } + return utf8; +} + +/* Recode a UTF-16 string with big-endian byte ordering to UTF-8 */ +unsigned char* utf16BEdecode(const unsigned char *utf16, unsigned char *utf8, + int count) +{ + unsigned long ucs; + + while (count > 0) { + if (*utf16 >= 0xD8 && *utf16 < 0xE0) { /* Check for a surrogate pair */ + ucs = 0x10000 + (((utf16[0] - 0xD8) << 18) | (utf16[1] << 10) + | ((utf16[2] - 0xDC) << 8) | utf16[3]); + utf16 += 4; + count -= 2; + } else { + ucs = (utf16[0] << 8) | utf16[1]; + utf16 += 2; + count -= 1; + } + utf8 = utf8encode(ucs, utf8); + } + return utf8; +} + +/* Recode any UTF-16 string to UTF-8 */ +unsigned char* utf16decode(const unsigned char *utf16, unsigned char *utf8, + unsigned int count) +{ + unsigned long ucs; + + ucs = *(utf16++) << 8; + ucs |= *(utf16++); + + if (ucs == 0xFEFF) /* Check for BOM */ + return utf16BEdecode(utf16, utf8, count-1); + else if (ucs == 0xFFFE) + return utf16LEdecode(utf16, utf8, count-1); + else { /* ADDME: Should default be LE or BE? */ + utf16 -= 2; + return utf16BEdecode(utf16, utf8, count); + } +} + +/* Return the number of UTF-8 chars in a string */ +unsigned long utf8length(const unsigned char *utf8) +{ + unsigned long l = 0; + + while (*utf8 != 0) + if ((*utf8++ & MASK) != COMP) + l++; + + return l; +} + +/* Decode 1 UTF-8 char and return a pointer to the next char. */ +const unsigned char* utf8decode(const unsigned char *utf8, unsigned short *ucs) +{ + unsigned char c = *utf8++; + unsigned long code; + int tail = 0; + + if ((c <= 0x7f) || (c >= 0xc2)) { + /* Start of new character. */ + if (c < 0x80) { /* U-00000000 - U-0000007F, 1 byte */ + code = c; + } else if (c < 0xe0) { /* U-00000080 - U-000007FF, 2 bytes */ + tail = 1; + code = c & 0x1f; + } else if (c < 0xf0) { /* U-00000800 - U-0000FFFF, 3 bytes */ + tail = 2; + code = c & 0x0f; + } else if (c < 0xf5) { /* U-00010000 - U-001FFFFF, 4 bytes */ + tail = 3; + code = c & 0x07; + } else { + /* Invalid size. */ + code = 0xfffd; + } + + while (tail-- && ((c = *utf8++) != 0)) { + if ((c & 0xc0) == 0x80) { + /* Valid continuation character. */ + code = (code << 6) | (c & 0x3f); + + } else { + /* Invalid continuation char */ + code = 0xfffd; + utf8--; + break; + } + } + } else { + /* Invalid UTF-8 char */ + code = 0xfffd; + } + /* currently we don't support chars above U-FFFF */ + *ucs = (code < 0x10000) ? code : 0xfffd; + return utf8; +} + +void set_codepage(int cp) +{ + default_codepage = cp; + return; +} + +/* seek to a given char in a utf8 string and + return its start position in the string */ +int utf8seek(const unsigned char* utf8, int offset) +{ + int pos = 0; + + while (offset--) { + pos++; + while ((utf8[pos] & MASK) == COMP) + pos++; + } + return pos; +} Index: utils/emuriver/src/flashimgtool/Makefile.am =================================================================== --- utils/emuriver/src/flashimgtool/Makefile.am (revision 0) +++ utils/emuriver/src/flashimgtool/Makefile.am (revision 0) @@ -0,0 +1,9 @@ +bin_PROGRAMS = flashimgtool + +flashimgtool_SOURCES = flashimgtool.c flashimgtool.h disk.h disk.c \ + fat.h fat.c ata.h ata.c \ + file.h file.c dir.h dir.c unicode.c rbunicode.h \ + flashimg.c flashimg.h flashdisk.c flashdisk.h +flashimgtool_LDADD = ../common/libcommon.a + +INCLUDES = -I$(top_srcdir)/src/common \ No newline at end of file Index: utils/emuriver/src/flashimgtool/flashimgtool.c =================================================================== --- utils/emuriver/src/flashimgtool/flashimgtool.c (revision 0) +++ utils/emuriver/src/flashimgtool/flashimgtool.c (revision 0) @@ -0,0 +1,191 @@ +#include +#include +#include "common.h" +#include "disk.h" +#include "flashimg.h" +#include "flashdisk.h" +#include "ata.h" +#include "dir.h" + +static struct flash_disk *flash_disk; +static int option_debug = 0; + +void debugf(const char *format, ...) { + if (option_debug) { + va_list ap; + fprintf(stderr, "debug: "); + va_start(ap, format); + vfprintf(stderr, format, ap); + va_end(ap); + } +} + +int init_flash(char *name) { + struct flashimg *flash_img; + + flash_img = flashimg_create(FLASHIMG_256_8, name, 0); + if (!flash_img) + return -1; + flash_disk = flash_disk_create(flash_img); + if (!flash_disk) { + flashimg_free(flash_img); + return -1; + } + ata_init(flash_disk); + return 0; +} + +int cmd_ls(int argc, char *argv[]) { + DIR* dir; + struct dirent* entry; + + if (argc < 1){ + error("Usage: ls playerdirectory"); + return 1; + } + dir = opendir(argv[0]); + if (dir) { + while ((entry = readdir(dir))) + printf("%-15s %10d\n", entry->d_name, entry->size); + closedir(dir); + return 0; + } else { + error("could not open dir %s", argv[0]); + return 1; + } +} + +int cmd_mkdir(int argc, char *argv[]) { + if (argc < 1){ + error("Usage: mkdir playerdirectory"); + return 1; + } + if (mkdir(argv[0], 0) < 0) { + error("could not create dir %s", argv[0]); + return 1; + } + return 0; +} + +int cmd_get(int argc, char *argv[]) { + int fd; + FILE *fp; + char buf[4096]; + + if (argc < 2){ + error("Usage: get playerfile destinationfile"); + return 1; + } + fd = open(argv[0], O_RDONLY); + if (fd < 0) { + error("could not open file %s", argv[0]); + return 1; + } + fp = fopen(argv[1], "w"); + if (!fp) { + close(fd); + error_sys("could not open file %s", argv[1]); + return 1; + } + while (1) { + int r = read(fd, buf, sizeof(buf)); + if (r < 0) { + close(fd); + fclose(fp); + error("error while reading %s", argv[0]); + return 1; + } + if (r == 0) break; + r = fwrite(buf, r, 1, fp); + if (r != 1) { + close(fd); + fclose(fp); + error("error while writing %s", argv[1]); + return 1; + } + } + close(fd); + fclose(fp); + return 0; +} + +int cmd_put(int argc, char *argv[]) { + int fd; + FILE *fp; + char buf[4096]; + + if (argc < 2){ + error("Usage: put sourcefile playerfile"); + return 1; + } + fd = creat(argv[1], O_WRONLY); + if (fd < 0) { + error("could not open file %s", argv[1]); + return 1; + } + fp = fopen(argv[0], "r"); + if (!fp) { + close(fd); + error_sys("could not open file %s", argv[0]); + return 1; + } + do { + int rw; + int r = fread(buf, 1, sizeof(buf), fp); + if (ferror(fp)) { + close(fd); + fclose(fp); + error("error while reading %s", argv[0]); + return 1; + } + if (r) { + rw = write(fd, buf, r); + if (rw != r) { + close(fd); + fclose(fp); + error("error while writing %s", argv[1]); + return 1; + } + } + } while (!feof(fp)); + close(fd); + if (fclose(fp) == EOF) { + error_sys("error while closing %s", argv[1]); + return 1; + } + return 0; +} + +struct { + char *cmd; + int (*func)(int argc, char* argv[]); +} func_tab[] = { + {"ls", cmd_ls}, + {"mkdir", cmd_mkdir}, + {"get", cmd_get}, + {"put", cmd_put}, + /* {"rm", cmd_rm}, + */ {NULL, NULL} +}; + +int main(int argc, char *argv[]) { + int i; + set_program_name(argv[0]); + + if (argc < 3){ + error("Usage: %s flash-image command argument...", argv[0]); + return 1; + } + + if (init_flash(argv[1]) < 0) + return 1; + if (disk_mount_all() <= 0) { + printf("mount failed\n"); + return 1; + } + for (i = 0; func_tab[i].cmd; i++) + if (!strcmp(argv[2], func_tab[i].cmd)) + return (*func_tab[i].func)(argc - 3, argv + 3); + + return 0; +} Index: utils/emuriver/src/flashimgtool/disk.c =================================================================== --- utils/emuriver/src/flashimgtool/disk.c (revision 0) +++ utils/emuriver/src/flashimgtool/disk.c (revision 0) @@ -0,0 +1,198 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: disk.c,v 1.10 2006-08-31 19:19:35 dave Exp $ + * + * Copyright (C) 2002 by Björn Stenberg + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include +#include "ata.h" +/* +#include "debug.h" +*/ +#include "fat.h" +#ifdef HAVE_MMC +#include "ata_mmc.h" +#endif +#include "file.h" /* for release_dirs() */ +#include "dir.h" /* for release_files() */ +#include "disk.h" +#include "flashimgtool.h" + +/* Partition table entry layout: + ----------------------- + 0: 0x80 - active + 1: starting head + 2: starting sector + 3: starting cylinder + 4: partition type + 5: end head + 6: end sector + 7: end cylinder + 8-11: starting sector (LBA) + 12-15: nr of sectors in partition +*/ + +#define BYTES2INT32(array,pos) \ + ((long)array[pos] | ((long)array[pos+1] << 8 ) | \ + ((long)array[pos+2] << 16 ) | ((long)array[pos+3] << 24 )) + +static struct partinfo part[8]; /* space for 4 partitions on 2 drives */ +static int vol_drive[NUM_VOLUMES]; /* mounted to which drive (-1 if none) */ + +struct partinfo* disk_init(IF_MV_NONVOID(int drive)) +{ + int i; + unsigned char sector[512]; +#ifdef HAVE_MULTIVOLUME + /* For each drive, start at a different position, in order not to destroy + the first entry of drive 0. + That one is needed to calculate config sector position. */ + struct partinfo* pinfo = &part[drive*4]; + if ((size_t)drive >= sizeof(part)/sizeof(*part)/4) + return NULL; /* out of space in table */ +#else + struct partinfo* pinfo = part; +#endif + + ata_read_sectors(IF_MV2(drive,) 0,1,§or); + + /* check that the boot sector is initialized */ + if ( (sector[510] != 0x55) || + (sector[511] != 0xaa)) { + DEBUGF("Bad boot sector signature\n"); + return NULL; + } + + /* parse partitions */ + for ( i=0; i<4; i++ ) { + unsigned char* ptr = sector + 0x1be + 16*i; + pinfo[i].type = ptr[4]; + pinfo[i].start = BYTES2INT32(ptr, 8); + pinfo[i].size = BYTES2INT32(ptr, 12); + + DEBUGF("Part%d: Type %02x, start: %08lx size: %08lx\n", + i,pinfo[i].type,pinfo[i].start,pinfo[i].size); + + /* extended? */ + if ( pinfo[i].type == 5 ) { + /* not handled yet */ + } + } + + return pinfo; +} + +struct partinfo* disk_partinfo(int partition) +{ + return &part[partition]; +} + +int disk_mount_all(void) +{ + int mounted; + int i; + +#if defined(HAVE_MMC) && defined(HAVE_HOTSWAP) + mmc_enable_monitoring(false); +#endif + + fat_init(); /* reset all mounted partitions */ + for (i=0; i +#include +#include "flashimg.h" +#include "flashimgtool.h" +#include "common.h" + +struct flashimg *flashimg_create(int model, char *fname, int offset) { + struct flashimg *flash; + + flash = xmalloc(sizeof(struct flashimg)); + if (!flash) + return NULL; + + flash->model = model; + flash->fp = fopen(fname, "r+b"); + if (!flash->fp) { + error_sys("%s: ", fname); + free(flash); + return NULL; + } + return flash; +} + +void flashimg_free(struct flashimg *flash) { + if (flash) { + if (flash->fp) + fclose(flash->fp); + free(flash); + } +} + +static int readwrite_fragment(FILE *fp, size_t offset, + size_t fstart, size_t flength, + char *buf, size_t bstart, size_t blength, + int write_op) { + size_t foffset, boffset; + size_t length; + + if (fstart > bstart) { + foffset = 0; + boffset = fstart - bstart; + } else { + foffset = bstart - fstart; + boffset = 0; + } + if (flength <= foffset || blength <= boffset) + return 0; + length = MIN(flength - boffset, blength - boffset); + + if (length > 0) { + int res; + if (fseek(fp, offset + foffset, SEEK_SET) == -1) + return -1; + if (write_op) + res = fwrite(buf + boffset, 1, length, fp); + else + res = fread(buf + boffset, 1, length, fp); + if (res != length) + return -1; + } + return 0; +} + +int flashimg_write(struct flashimg *flash, const char *buf, + int page, int start, int length) { + if (readwrite_fragment(flash->fp, flash->offset + page * 64, + 2048, 64, + (char *)buf, start, length, 1)) + return -1; + if (readwrite_fragment(flash->fp, + flash->offset + page * 2048 + + flashimg_n_pages(flash) * 64, + 0, 2048, + (char *)buf, start, length, 1)) + return -1; + return 0; +} + +int flashimg_read(struct flashimg *flash, char *buf, + int page, int start, int length) { + if (readwrite_fragment(flash->fp, flash->offset + page * 64, + 2048, 64, + buf, start, length, 0)) + return -1; + if (readwrite_fragment(flash->fp, + flash->offset + page * 2048 + + flashimg_n_pages(flash) * 64, + 0, 2048, + buf, start, length, 0)) + return -1; + return 0; +} + +int flashimg_n_pages(struct flashimg *flash) { + switch (flash->model) { + case FLASHIMG_256_8: + return 128 * 1024; + case FLASHIMG_512_8: + return 256 * 1024; + case FLASHIMG_1024_8: + return 512 * 1024; + default: + return 0; + } +} Index: utils/emuriver/src/flashimgtool/flashimgtool.h =================================================================== --- utils/emuriver/src/flashimgtool/flashimgtool.h (revision 0) +++ utils/emuriver/src/flashimgtool/flashimgtool.h (revision 0) @@ -0,0 +1,61 @@ +#ifndef _FLASHIMGTOOL_H_ +#define _FLASHIMGTOOL_H_ + +#include "config.h" + +#define DEBUGF debugf +#define LDEBUGF(...) +#define panicf(...) +#define logf(...) + +#define YEAR 2006 +#define MONTH 01 +#define DAY 01 + +#define HAVE_FAT16SUPPORT + +void debugf(const char *format, ...); + +struct mutex { }; + +static inline mutex_init(struct mutex *m) { } +static inline mutex_lock(struct mutex *m) { } +static inline mutex_unlock(struct mutex *m) { } + +static inline unsigned short swap16(unsigned short value) + /* + result[15..8] = value[ 7..0]; + result[ 7..0] = value[15..8]; + */ +{ + return (value >> 8) | (value << 8); +} + +static inline unsigned long swap32(unsigned long value) + /* + result[31..24] = value[ 7.. 0]; + result[23..16] = value[15.. 8]; + result[15.. 8] = value[23..16]; + result[ 7.. 0] = value[31..24]; + */ +{ + unsigned long hi = swap16(value >> 16); + unsigned long lo = swap16(value & 0xffff); + return (lo << 16) | hi; +} + +#ifdef CONFIG_BIGENDIAN +#define htole16(x) swap16(x) +#define letoh16(x) swap16(x) +#define htole32(x) swap32(x) +#define letoh32(x) swap32(x) +#else +#define htole16(x) (x) +#define letoh16(x) (x) +#define htole32(x) (x) +#define letoh32(x) (x) +#endif + +#define MIN(a, b) (((a)<(b))?(a):(b)) + +#endif Index: utils/emuriver/src/lcd.h =================================================================== --- utils/emuriver/src/lcd.h (revision 0) +++ utils/emuriver/src/lcd.h (revision 0) @@ -0,0 +1,47 @@ +/* iRiver iFP 7XX Emulator + Copyright (C) 2005 Tomasz Malesinski + + 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 */ + +#ifndef _LCD_H_ +#define _LCD_H_ + +#include + +#include "emuriver.h" + +#define LCD_WIDTH 132 +#define LCD_HEIGHT 65 + +#define LCDFLG_ADC 1 +#define LCDFLG_DISPLAY_ON 2 +#define LCDFLG_REF_VOLTAGE_SEL 4 +#define LCDFLG_SET_STATIC_IND_MODE 8 + +struct lcd { + uint8 ddram[9 * 132]; + int flags; + int page, col; +}; + +uint32 lcd_read(struct lcd *lcd, uint32 adr); +void lcd_write(struct lcd *lcd, uint32 adr, uint32 val); +struct lcd *create_lcd(void); +void free_lcd(struct lcd *lcd); + +int lcd_get_pixel(struct lcd *lcd, int x, int y); +void lcd_print_small(struct lcd *lcd, FILE *fp); + +#endif Index: utils/emuriver/src/common/xmalloc.c =================================================================== --- utils/emuriver/src/common/xmalloc.c (revision 0) +++ utils/emuriver/src/common/xmalloc.c (revision 0) @@ -0,0 +1,10 @@ +#include +#include "common.h" + +void *xmalloc(size_t size) { + void *p = malloc(size); + if (!p) + error("out of memory"); + return p; +} + Index: utils/emuriver/src/common/errormsg.c =================================================================== --- utils/emuriver/src/common/errormsg.c (revision 0) +++ utils/emuriver/src/common/errormsg.c (revision 0) @@ -0,0 +1,28 @@ +#include +#include +#include +#include "common.h" + +static char *program_name; + +void set_program_name(char *s) { + program_name = s; +} + +void error(const char *format, ...) { + va_list ap; + fprintf(stderr, "%s: ", program_name); + va_start(ap, format); + vfprintf(stderr, format, ap); + va_end(ap); + fputc('\n', stderr); +} + +void error_sys(const char *format, ...) { + va_list ap; + fprintf(stderr, "%s: ", program_name); + va_start(ap, format); + vfprintf(stderr, format, ap); + va_end(ap); + fprintf(stderr, "%s\n", strerror(errno)); +} Index: utils/emuriver/src/common/Makefile.in =================================================================== --- utils/emuriver/src/common/Makefile.in (revision 0) +++ utils/emuriver/src/common/Makefile.in (revision 0) @@ -0,0 +1,269 @@ +# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999, 2001 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. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = ../.. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +CC = @CC@ +CURSES_LIB = @CURSES_LIB@ +HAVE_LIB = @HAVE_LIB@ +LIB = @LIB@ +LTLIB = @LTLIB@ +MAKEINFO = @MAKEINFO@ +PACKAGE = @PACKAGE@ +RANLIB = @RANLIB@ +SDL_CFLAGS = @SDL_CFLAGS@ +SDL_CONFIG = @SDL_CONFIG@ +SDL_LIBS = @SDL_LIBS@ +UI_OBJS = @UI_OBJS@ +VERSION = @VERSION@ + +noinst_LIBRARIES = libcommon.a + +libcommon_a_SOURCES = errormsg.c xmalloc.c common.h +mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs +CONFIG_HEADER = ../../config.h +CONFIG_CLEAN_FILES = +LIBRARIES = $(noinst_LIBRARIES) + + +DEFS = @DEFS@ -I. -I$(srcdir) -I../.. +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +libcommon_a_LIBADD = +libcommon_a_OBJECTS = errormsg.o xmalloc.o +AR = ar +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP_ENV = --best +SOURCES = $(libcommon_a_SOURCES) +OBJECTS = $(libcommon_a_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .o .s +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps src/common/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-noinstLIBRARIES: + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) + +distclean-noinstLIBRARIES: + +maintainer-clean-noinstLIBRARIES: + +.c.o: + $(COMPILE) -c $< + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +libcommon.a: $(libcommon_a_OBJECTS) $(libcommon_a_DEPENDENCIES) + -rm -f libcommon.a + $(AR) cru libcommon.a $(libcommon_a_OBJECTS) $(libcommon_a_LIBADD) + $(RANLIB) libcommon.a + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags -o $$here/TAGS $(ETAGS_ARGS) $$tags $$unique $(LISP)) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = src/common + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +errormsg.o: errormsg.c common.h +xmalloc.o: xmalloc.c common.h + +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: +install-exec: install-exec-am + +install-data-am: +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: +uninstall: uninstall-am +all-am: Makefile $(LIBRARIES) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-noinstLIBRARIES mostlyclean-compile \ + mostlyclean-tags mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-noinstLIBRARIES clean-compile clean-tags clean-generic \ + mostlyclean-am + +clean: clean-am + +distclean-am: distclean-noinstLIBRARIES distclean-compile \ + distclean-tags distclean-generic clean-am + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-noinstLIBRARIES \ + maintainer-clean-compile maintainer-clean-tags \ + maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \ +clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \ +mostlyclean-compile distclean-compile clean-compile \ +maintainer-clean-compile tags mostlyclean-tags distclean-tags \ +clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \ +check-am installcheck-am installcheck install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +# 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: Index: utils/emuriver/src/common/Makefile.am =================================================================== --- utils/emuriver/src/common/Makefile.am (revision 0) +++ utils/emuriver/src/common/Makefile.am (revision 0) @@ -0,0 +1,3 @@ +noinst_LIBRARIES = libcommon.a + +libcommon_a_SOURCES = errormsg.c xmalloc.c common.h Index: utils/emuriver/src/common/common.h =================================================================== --- utils/emuriver/src/common/common.h (revision 0) +++ utils/emuriver/src/common/common.h (revision 0) @@ -0,0 +1,11 @@ +#ifndef _COMMON_H_ +#define _COMMON_H_ + +#include + +void set_program_name(char *s); +void error(const char *format, ...); +void error_sys(const char *format, ...); +void *xmalloc(size_t size); + +#endif Index: utils/emuriver/src/memory.c =================================================================== --- utils/emuriver/src/memory.c (revision 0) +++ utils/emuriver/src/memory.c (revision 0) @@ -0,0 +1,319 @@ +/* iRiver iFP 7XX Emulator + Copyright (C) 2005 Tomasz Malesinski + + 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 */ + +#include +#include + +#include "emuriver.h" +#include "memory.h" +#include "cpu.h" +#include "log.h" + +uint32 get_word(uint8 *p) { + return ((uint32)p[3] << 24) | ((uint32)p[2] << 16) + | ((uint32)p[1] << 8) | p[0]; +} + +uint32 get_half_word(uint8 *p) { + return ((uint32)p[1] << 8) | p[0]; +} + +void put_word(uint8 *p, uint32 val) { + p[3] = val >> 24; + p[2] = (val >> 16) & 0xff; + p[1] = (val >> 8) & 0xff; + p[0] = val & 0xff; +} + +void put_half_word(uint8 *p, uint32 val) { + p[1] = (val >> 8) & 0xff; + p[0] = val & 0xff; +} + +uint8 read_void(void *data, uint32 adr, struct profile *profile, + uint32 req_adr) { + logmsg(LOG_MEMORY, 5, "void read from %8x\n", adr); + return 0xff; +} + +uint32 read_half_word_void(void *data, uint32 adr, struct profile *profile, + uint32 req_adr) { + logmsg(LOG_MEMORY, 5, "void read from %8x (pc=%8x)\n", adr, cpu->reg[15] - 4); + return 0xffff; +} + +uint32 read_word_void(void *data, uint32 adr, struct profile *profile, + uint32 req_adr) { + logmsg(LOG_MEMORY, 5, "void read from %8x (pc=%8x)\n", adr, cpu->reg[15] - 4); + return 0xffffffff; +} + +void write_void(void *data, uint32 adr, uint8 val, struct profile *profile, + uint32 req_adr) { + logmsg(LOG_MEMORY, 5, "void write %8x to %8x\n", val, adr); +} + +void write_half_word_void(void *data, uint32 adr, uint32 val, + struct profile *profile, uint32 req_adr) { + logmsg(LOG_MEMORY, 5, "void write %8x to %8x\n", val, adr); +} + +void write_word_void(void *data, uint32 adr, uint32 val, + struct profile *profile, uint32 req_adr) { + logmsg(LOG_MEMORY, 5, "void write %8x to %8x\n", val, adr); +} + +static void rom_write(void *data, uint32 adr, uint8 val, + struct profile *profile, uint32 req_adr) { + logmsg(LOG_MEMORY, 5, "write %8x to ROM at %8x\n", val, adr); +} + +static void rom_write_half_word(void *data, uint32 adr, uint32 val, + struct profile *profile, uint32 req_adr) { + logmsg(LOG_MEMORY, 5, "write %8x to ROM at %8x\n", val, adr); +} + +static void rom_write_word(void *data, uint32 adr, uint32 val, + struct profile *profile, uint32 req_adr) { + logmsg(LOG_MEMORY, 5, "write %8x to ROM at %8x\n", val, adr); +} + +static uint8 block_read(void *data, uint32 adr, + struct profile *profile, uint32 req_adr) { + struct mem_block *b = data; + if (b->profile_ctr >= 0) + profile_count(profile, req_adr, b->profile_ctr, 1); + return b->mem[adr & b->mask]; +} + +static uint32 block_read_half_word(void *data, uint32 adr, + struct profile *profile, uint32 req_adr) { + struct mem_block *b = data; + uint32 r = 0; + int i; + if (b->profile_ctr >= 0) + profile_count(profile, req_adr, b->profile_ctr, 1); + for (i = 1; i >= 0; i--) + r = (r << 8) | b->mem[(adr & b->mask) + i]; + return r; +} + +static uint32 block_read_word(void *data, uint32 adr, + struct profile *profile, uint32 req_adr) { + struct mem_block *b = data; + uint32 r = 0; + int i; + if (b->profile_ctr >= 0) + profile_count(profile, req_adr, b->profile_ctr, 1); + for (i = 3; i >= 0; i--) + r = (r << 8) | b->mem[(adr & b->mask) + i]; + return r; +} + +static void block_write(void *data, uint32 adr, uint8 val, + struct profile *profile, uint32 req_adr) { + struct mem_block *b = data; + if (b->profile_ctr >= 0) + profile_count(profile, req_adr, b->profile_ctr, 1); + b->mem[adr & b->mask] = val; +} + +static void block_write_half_word(void *data, uint32 adr, uint32 val, + struct profile *profile, uint32 req_adr) { + struct mem_block *b = data; + int i; + if (b->profile_ctr >= 0) + profile_count(profile, req_adr, b->profile_ctr, 1); + for (i = 0; i < 2; i++) + b->mem[(adr & b->mask) + i] = (val >> (i * 8)) & 0xff; +} + +static void block_write_word(void *data, uint32 adr, uint32 val, + struct profile *profile, uint32 req_adr) { + struct mem_block *b = data; + int i; + if (b->profile_ctr >= 0) + profile_count(profile, req_adr, b->profile_ctr, 1); + for (i = 0; i < 4; i++) + b->mem[(adr & b->mask) + i] = (val >> (i * 8)) & 0xff; +} + +uint8 memory_read(struct memory *memory, uint32 adr, + struct profile *profile, uint32 req_adr) { + struct mem_region *r = &(memory->region[adr >> 16]); + return (*(r->read))(r->data, adr, profile, req_adr); +} + +void memory_write(struct memory *memory, uint32 adr, uint8 val, + struct profile *profile, uint32 req_adr) { + struct mem_region *r = &(memory->region[adr >> 16]); + (*(r->write))(r->data, adr, val, profile, req_adr); +} + +uint32 memory_read_half_word(struct memory *memory, uint32 adr, + struct profile *profile, uint32 req_adr) { + struct mem_region *r = &(memory->region[adr >> 16]); + return (*(r->read_half_word))(r->data, adr, profile, req_adr); +} + +void memory_write_half_word(struct memory *memory, uint32 adr, uint32 val, + struct profile *profile, uint32 req_adr) { + struct mem_region *r = &(memory->region[adr >> 16]); + (*(r->write_half_word))(r->data, adr, val, profile, req_adr); +} + +uint32 memory_read_word(struct memory *memory, uint32 adr, + struct profile *profile, uint32 req_adr) { + struct mem_region *r = &(memory->region[adr >> 16]); + return (*(r->read_word))(r->data, adr, profile, req_adr); +} + +void memory_write_word(struct memory *memory, uint32 adr, uint32 val, + struct profile *profile, uint32 req_adr) { + struct mem_region *r = &(memory->region[adr >> 16]); + (*(r->write_word))(r->data, adr, val, profile, req_adr); +} + +void set_area(struct memory *mem, uint32 start, uint32 end, + uint8 (*read)(void *, uint32, struct profile *, uint32), + void (*write)(void *, uint32, uint8, struct profile *, uint32), + uint32 (*read_half_word)(void *, uint32, + struct profile *, uint32), + void (*write_half_word)(void *, uint32, uint32, + struct profile *, uint32), + uint32 (*read_word)(void *, uint32, struct profile *, uint32), + void (*write_word)(void *, uint32, uint32, + struct profile *, uint32), + void *data) { + int r; + for (r = start >> 16; r <= end >> 16; r++) { + mem->region[r].read = read; + mem->region[r].write = write; + mem->region[r].read_half_word = read_half_word; + mem->region[r].write_half_word = write_half_word; + mem->region[r].read_word = read_word; + mem->region[r].write_word = write_word; + mem->region[r].data = data; + } +} + +void memory_copy_configuration(struct memory *dest_memory, + uint32 dest_start, uint32 dest_end, + struct memory *src_memory, + uint32 src_start) { + int r; + int s = src_start >> 16; + for (r = dest_start >> 16; r <= dest_end >> 16; r++) + dest_memory->region[r] = src_memory->region[s++]; +} + +struct memory *create_memory(void) { + struct memory *m; + int i; + + m = xmalloc(sizeof(struct memory)); + if (!m) + return NULL; + + for (i = 0; i < (1 << 16); i++) { + m->region[i].read = read_void; + m->region[i].write = write_void; + m->region[i].read_half_word = read_half_word_void; + m->region[i].write_half_word = write_half_word_void; + m->region[i].read_word = read_word_void; + m->region[i].write_word = write_word_void; + } + + return m; +} + +static struct mem_block *create_memory_block(uint32 len) { + uint8 *area; + struct mem_block *block; + + area = xmalloc(len); + if (!area) return NULL; + + block = xmalloc(sizeof(struct mem_block)); + if (!block) { + free(area); + return NULL; + } + + block->mem = area; + block->len = len; + block->mask = len - 1; + block->profile_ctr = -1; + + return block; +} + +void free_memory_block(struct mem_block *block) { + free(block->mem); + free(block); +} + +struct mem_block *create_memory_area_rom(struct memory *mem, uint32 adr, + uint32 len, char *file) { + struct mem_block *block; + FILE *fp; + + block = create_memory_block(len); + if (!block) return NULL; + + fp = fopen(file, "rb"); + if (!fp) { + error_sys("%s: ", file); + free_memory_block(block); + return NULL; + } + + fread(block->mem, 1, len, fp); + fclose(fp); + + block->rom = 1; + + set_area(mem, adr, adr + len - 1, + block_read, rom_write, + block_read_half_word, rom_write_half_word, + block_read_word, rom_write_word, + block); + + return block; +} + +struct mem_block *create_memory_area_ram(struct memory *mem, uint32 adr, + uint32 len, int profile_ctr) { + struct mem_block *block; + FILE *fp; + + block = create_memory_block(len); + if (!block) + return NULL; + block->profile_ctr = profile_ctr; + + block->rom = 0; + memset(block->mem, 0, len); + + set_area(mem, adr, adr + len - 1, + block_read, block_write, + block_read_half_word, block_write_half_word, + block_read_word, block_write_word, + block); + + return block; +} Index: utils/emuriver/src/memory.h =================================================================== --- utils/emuriver/src/memory.h (revision 0) +++ utils/emuriver/src/memory.h (revision 0) @@ -0,0 +1,101 @@ +/* iRiver iFP 7XX Emulator + Copyright (C) 2005 Tomasz Malesinski + + 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 */ + +#ifndef _MEMORY_H_ +#define _MEMORY_H_ + +#include "emuriver.h" +#include "profile.h" + +struct mem_region { + uint8 (*read)(void *data, uint32 adr, + struct profile *profile, uint32 req_adr); + void (*write)(void *data, uint32 adr, uint8 val, + struct profile *profile, uint32 req_adr); + uint32 (*read_half_word)(void *data, uint32 adr, + struct profile *profile, uint32 req_adr); + void (*write_half_word)(void *data, uint32 adr, uint32 val, + struct profile *profile, uint32 req_adr); + uint32 (*read_word)(void *data, uint32 adr, + struct profile *profile, uint32 req_adr); + void (*write_word)(void *data, uint32 adr, uint32 val, + struct profile *profile, uint32 req_adr); + void *data; +}; + +struct mem_block { + uint8 *mem; + int profile_ctr; + uint32 mask; + uint32 len; + int rom; + int profiling; +}; + +struct memory { + struct mem_region region[1 << 16]; +}; + +uint32 get_word(uint8 *p); +uint32 get_half_word(uint8 *p); +void put_word(uint8 *p, uint32 val); +void put_half_word(uint8 *p, uint32 val); + +struct memory *create_memory(void); +struct mem_block *create_memory_area_rom(struct memory *mem, uint32 adr, + uint32 len, char *file); +struct mem_block *create_memory_area_ram(struct memory *mem, uint32 adr, + uint32 len, int profile_ctr); +void free_memory_block(struct mem_block *block); +void dump_profile(FILE *fp, struct mem_block *block, uint32 offset); + +uint32 memory_read_word(struct memory *, uint32 adr, + struct profile *profile, uint32 req_adr); +void memory_write_word(struct memory *, uint32 adr, uint32 val, + struct profile *profile, uint32 req_adr); + +uint8 read_void(void *data, uint32 adr, + struct profile *profile, uint32 req_adr); +uint32 read_half_word_void(void *data, uint32 adr, + struct profile *profile, uint32 req_adr); +uint32 read_word_void(void *data, uint32 adr, + struct profile *profile, uint32 req_adr); +void write_void(void *data, uint32 adr, uint8 val, + struct profile *profile, uint32 req_adr); +void write_half_word_void(void *data, uint32 adr, uint32 val, + struct profile *profile, uint32 req_adr); +void write_word_void(void *data, uint32 adr, uint32 val, + struct profile *profile, uint32 req_adr); + +void memory_copy_configuration(struct memory *dest_memory, + uint32 dest_start, uint32 dest_end, + struct memory *src_memory, + uint32 src_start); + +void set_area(struct memory *mem, uint32 start, uint32 end, + uint8 (*read)(void *, uint32, struct profile *, uint32), + void (*write)(void *, uint32, uint8, struct profile *, uint32), + uint32 (*read_half_word)(void *, uint32, + struct profile *, uint32), + void (*write_half_word)(void *, uint32, uint32, + struct profile *, uint32), + uint32 (*read_word)(void *, uint32, struct profile *, uint32), + void (*write_word)(void *, uint32, uint32, + struct profile *, uint32), + void *data); + +#endif Index: utils/emuriver/src/log.c =================================================================== --- utils/emuriver/src/log.c (revision 0) +++ utils/emuriver/src/log.c (revision 0) @@ -0,0 +1,77 @@ +/* iRiver iFP 7XX Emulator + Copyright (C) 2005 Tomasz Malesinski + + 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 */ + +#include +#include + +#include "log.h" + +static FILE *log_fp = NULL; +static int log_indent = 0; + +static int log_level[] = { + 50, /* LOG_GENERAL */ + 10, /* LOG_GPIO */ + 10, /* LOG_FLASH */ + 5, /* LOG_LCD */ + 9, /* LOG_FW_FLASH */ + 5, /* LOG_MEMORY */ + 5, /* LOG_ADC */ + 5, /* LOG_TRACE */ + 10, /* LOG_GDB */ + 10, /* LOG_I2C */ + 10, /* LOG_CPU */ + 10, /* LOG_USB */ + 15, /* LOG_CGU */ +}; + +int log_check(int source, int level) { + return log_fp && level <= log_level[source]; +} + +void log_set_fp(FILE *fp) { + log_fp = fp; + log_indent = 0; +} + +int logmsg(int source, int level, const char *format, ...) { + va_list ap; + int r, i; + + if (!log_check(source, level)) + return 0; + + for (i = 0; i < log_indent; i++) + fputc(' ', log_fp); + + va_start(ap, format); + r = vfprintf(log_fp, format, ap); + va_end(ap); + return r; +} + +void log_reset_indent(void) { + log_indent = 0; +} + +void log_inc_indent(void) { + log_indent++; +} + +void log_dec_indent(void) { + log_indent--; +} Index: utils/emuriver/src/event.c =================================================================== --- utils/emuriver/src/event.c (revision 0) +++ utils/emuriver/src/event.c (revision 0) @@ -0,0 +1,65 @@ +/* iRiver iFP 7XX Emulator + Copyright (C) 2005 Tomasz Malesinski + + 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 */ + +#include +#include "event.h" + +static struct event *event_list; + +static int before(unsigned int t1, unsigned int t2) { + return (t2 - t1) < 0x80000000U; +} + +void init_events(void) { + event_list = NULL; +} + +void add_event(struct event *e) { + struct event *f = event_list; + if (!f || before(e->tick, f->tick)) { + e->next = f; + event_list = e; + } else { + while (f->next && before(f->next->tick, e->tick)) + f = f->next; + e->next = f->next; + f->next = e; + } +} + +void remove_event(struct event *e) { + struct event *prev = NULL; + struct event *i = event_list; + while (i && i != e) { + prev = i; + i = i->next; + } + if (i) { + if (prev) + prev->next = i->next; + else + event_list = i->next; + } +} + +void handle_events(unsigned int tick) { + while (event_list && !before(tick, event_list->tick)) { + struct event *e = event_list; + event_list = event_list->next; + (*(e->f))(e); + } +} Index: utils/emuriver/src/main.c =================================================================== --- utils/emuriver/src/main.c (revision 0) +++ utils/emuriver/src/main.c (revision 0) @@ -0,0 +1,389 @@ +/* iRiver iFP 7XX Emulator + Copyright (C) 2005 Tomasz Malesinski + + 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 */ + +#include +#include +#include +#include +#include + +#include "emuriver.h" +#include "memory.h" +#include "cpu.h" +#include "hardware.h" +#include "trace.h" +#include "trainer.h" +#include "gdb.h" +#include "ui.h" +#include "flash.h" +#include "profile.h" + +struct memory *memory, *phys_memory; +struct cpu *cpu; +struct hardware *hardware; + +struct mem_block *iram, *dram, *xram; + +char *program_name; + +#define MODEL_790 0 +#define MODEL_795 1 +#define MODEL_799 2 + +int option_gdb = 0; +int option_disable_ui = 0; +int option_profile = 0; +int option_model = MODEL_790; +int option_extra_memory = 0; +int option_startup_hold_mode = 0; +int option_startup_hold_on = 0; + +char *log_file = NULL; +char *flash_file = "flash.img"; +char *prog_flash_file = "prog_flash.img"; +char *int_flash_file = "ifp1.bin"; +char *rockbox_file = NULL; + +struct option options[] = { + {"log", required_argument, NULL, 'l'}, + {"gdb", no_argument, NULL, 'g'}, + {"disable-ui", no_argument, NULL, 'n'}, + {"profile", no_argument, NULL, 'P'}, + {"flash-image", required_argument, NULL, 'f'}, + {"prog-flash-image", required_argument, NULL, 'p'}, + {"int-flash-image", required_argument, NULL, 'i'}, + {"rockbox", required_argument, NULL, 'r'}, + {"model", required_argument, NULL, 'm'}, + {"extra-memory", no_argument, NULL, 'x'}, + {0, 0, 0, 0} +}; + +void error(const char *format, ...) { + va_list ap; + fprintf(stderr, "%s: ", program_name); + va_start(ap, format); + vfprintf(stderr, format, ap); + va_end(ap); + fputc('\n', stderr); +} + +void error_sys(const char *format, ...) { + va_list ap; + fprintf(stderr, "%s: ", program_name); + va_start(ap, format); + vfprintf(stderr, format, ap); + va_end(ap); + fprintf(stderr, "%s\n", strerror(errno)); +} + +void *xmalloc(size_t size) { + void *p = malloc(size); + if (!p) + error("out of memory"); + return p; +} + +int set_iriver_memory(struct memory *memory) { + FILE *fp; + iram = create_memory_area_ram(memory, 0x400000, 0x10000, + PROFILE_CTR_IRAM_ACCESSES); + dram = create_memory_area_ram(memory, 0x24000000, 0x100000, + PROFILE_CTR_SRAM_ACCESSES); + if (option_extra_memory) + xram = create_memory_area_ram(memory, 0x30000000, 0x800000, + PROFILE_CTR_SRAM_ACCESSES); + else + xram = NULL; + + if (!iram || !dram || (option_extra_memory && !xram)) + return -1; + if (!create_memory_area_rom(memory, 0x10400000, 0x80000, + int_flash_file)) + return -1; + + if (rockbox_file) { + fp = fopen(rockbox_file, "rb"); + if (!fp) { + error_sys("%s: ", rockbox_file); + return -1; + } + fread(option_extra_memory ? xram->mem : dram->mem, 1, 0x80000, fp); + fclose(fp); + } + return 0; +} + +int set_mpio_memory(struct memory *memory) { + iram = create_memory_area_ram(memory, 0x20010000, 0x20000, -1); + if (!iram) + return -1; + return 0; +} + +int save_ram(struct mem_block *mem, char *file) { + FILE *fp; + fp = fopen(file, "wb"); + if (!fp) return -1; + fwrite(mem->mem, 1, 0x10000, fp); + fclose(fp); + + return 0; +} + +int load_binary(char *file, void *ptr, size_t len) { + FILE *fp; + fp = fopen(file, "rb"); + if (!fp) return -1; + fread(ptr, 1, len, fp); + fclose(fp); +} + +int init_iriver(struct cpu *cpu, struct memory *memory, int upgrade) { + if (set_iriver_memory(memory) < 0) + return -1; + + if (upgrade) { + load_binary("fw_upgrade.bin", iram->mem + 0x80, 0x10000); + cpu->reg[15] = 0x000080; + } else if (rockbox_file) + cpu->reg[15] = option_extra_memory ? 0x30000000 : 0x24000000; + else + cpu->reg[15] = 0x10400000; + return 0; +} + +void init_mpio(struct cpu *cpu, struct memory *memory, int upgrade) { + set_mpio_memory(memory); + if (upgrade) { + load_binary("mpio_upgrade.bin", iram->mem + 0x80, 0x10000); + cpu->reg[15] = 0x000080; + } else + cpu->reg[15] = 0x800000; +} + +int go(int n_cycles, int (*f)(void), int freq) { + int i, stop, r; + + i = 0; + while (n_cycles == 0 || i < n_cycles) { + stop = cpu_go(cpu, 1); + tick++; + + handle_events(tick); + + /* + if ((tick % 1000000) == 5000) { + cpu_irq(cpu); + set_irq_no(0x1c); + } + */ + + if (stop != CPU_STOP_NORMAL) + return stop; + + if (f && (tick % freq) == 0) { + r = (*f)(); + if (r) + return r; + } + + if (!option_disable_ui && (tick % 100000) == 0) { + ui_refresh(hardware->lcd); + if (ui_get_key(0)) return CPU_STOP_QUIT; + } + + i++; + } + + return CPU_STOP_NORMAL; +} + +int parse_options(int argc, char *argv[]) { + int c, index; + FILE *log_fp; + + while (1) { + c = getopt_long(argc, argv, "l:gnPf:p:i:m:x", options, &index); + if (c == -1) + break; + + switch (c) { + case '?': + return -1; + case 'l': + log_file = optarg; + break; + case 'g': + option_gdb = 1; + break; + case 'n': + option_disable_ui = 1; + break; + case 'P': + option_profile = 1; + break; + case 'f': + flash_file = optarg; + break; + case 'p': + prog_flash_file = optarg; + break; + case 'i': + int_flash_file = optarg; + break; + case 'r': + rockbox_file = optarg; + break; + case 'm': + if (!strcmp(optarg, "790")) + option_model = MODEL_790; + else if (!strcmp(optarg, "795")) + option_model = MODEL_795; + else if (!strcmp(optarg, "799")) + option_model = MODEL_799; + else { + fprintf(stderr, "%s: unknown model %s\n", argv[0], optarg); + return -1; + } + break; + case 'x': + option_extra_memory = 1; + break; + default: + abort(); + } + } + + if (log_file) { + log_fp = fopen(log_file, "w"); + if (log_fp) + log_set_fp(log_fp); + } + return 0; +} + +static int profile_counters[] = { + PROFILE_CTR_CPU_CYCLES, + PROFILE_CTR_IRAM_ACCESSES, + PROFILE_CTR_SRAM_ACCESSES, + PROFILE_CTR_CACHE_HITS, + PROFILE_CTR_CACHE_MISSES, + PROFILE_CTR_CACHE_FLUSHES, + -1 +}; + +int main(int argc, char *argv[]) { + int upgrade = 1; + struct flash *flash; + struct profile *profile; + int i; + + program_name = argv[0]; + if (parse_options(argc, argv) == -1) + return 1; + + init_events(); + + if (option_profile) { + profile = create_profile(); + if (!profile) + return 1; + + for (i = 0; profile_counters[i] >= 0; i++) { + if (profile_add_counter(profile, profile_counters[i], + 0xc00000, 0xcfffff) < 0) + return 1; + if (profile_add_counter(profile, profile_counters[i], + 0x400000, 0x40ffff) < 0) + return 1; + } + } else + profile = NULL; + + memory = create_memory(); + if (!memory) + return 1; + + phys_memory = create_memory(); + if (!phys_memory) + return 1; + + cpu = create_cpu(memory, profile); + if (!cpu) + return 1; + + hardware = create_hardware(); + if (!hardware) + return 1; + + switch (option_model) { + default: + case MODEL_790: + flash = create_flash(FLASH_256_8, flash_file, 0); + if (!flash) + return 1; + hardware_connect_flash(hardware, 0, flash); + break; + + case MODEL_799: + flash = create_flash(FLASH_512_8, flash_file, 0); + if (!flash) + return 1; + hardware_connect_flash(hardware, 0, flash); + flash = create_flash(FLASH_512_8, flash_file, 2112 * (1 << 18)); + if (!flash) + return 1; + hardware_connect_flash(hardware, 1, flash); + break; + } + + cpu_set_irq_p(cpu, check_irq, hardware); + + hardware_reset(hardware, phys_memory); + install_hardware(hardware, phys_memory); + + if (init_iriver(cpu, phys_memory, 0) < 0) + return 1; + + initialize_mmu(hardware, phys_memory, memory); + + trace_detect_firmware(memory); + trace_init(); + if (rockbox_file) + stack_tracing = 0; + + trainer_init(iram->mem); + + if (option_disable_ui || !ui_init()) { + if (option_gdb) + gdb_target(); + else + go(0, NULL, 0); + + if (!option_disable_ui) + ui_cleanup(); + } + + if (option_profile) { + FILE *fp = fopen("profile.out", "wt"); + if (!fp) return 1; + profile_dump(profile, fp); + fclose(fp); + } + + return 0; +} Index: utils/emuriver/src/event.h =================================================================== --- utils/emuriver/src/event.h (revision 0) +++ utils/emuriver/src/event.h (revision 0) @@ -0,0 +1,33 @@ +/* iRiver iFP 7XX Emulator + Copyright (C) 2005 Tomasz Malesinski + + 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 */ + +#ifndef _EVENT_H_ +#define _EVENT_H_ + +struct event { + struct event *next; + unsigned int tick; + void (*f)(struct event *); + void *data; +}; + +void init_events(void); +void add_event(struct event *e); +void remove_event(struct event *e); +void handle_events(unsigned int tick); + +#endif Index: utils/emuriver/src/log.h =================================================================== --- utils/emuriver/src/log.h (revision 0) +++ utils/emuriver/src/log.h (revision 0) @@ -0,0 +1,44 @@ +/* iRiver iFP 7XX Emulator + Copyright (C) 2005 Tomasz Malesinski + + 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 */ + +#ifndef _LOG_H_ +#define _LOG_H_ + +#include + +#define LOG_GENERAL 0 +#define LOG_GPIO 1 +#define LOG_FLASH 2 +#define LOG_LCD 3 +#define LOG_FW_FLASH 4 +#define LOG_MEMORY 5 +#define LOG_ADC 6 +#define LOG_TRACE 7 +#define LOG_GDB 8 +#define LOG_I2C 9 +#define LOG_CPU 10 +#define LOG_USB 11 +#define LOG_CGU 12 + +int log_check(int source, int level); +int logmsg(int source, int level, const char *format, ...); +void log_set_fp(FILE *fp); +void log_reset_indent(void); +void log_inc_indent(void); +void log_dec_indent(void); + +#endif Index: utils/emuriver/src/make_flash_img.c =================================================================== --- utils/emuriver/src/make_flash_img.c (revision 0) +++ utils/emuriver/src/make_flash_img.c (revision 0) @@ -0,0 +1,108 @@ +/* iRiver iFP 7XX Emulator + Copyright (C) 2005 Tomasz Malesinski + + 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 */ + +#include +#include +#include +#include + +char *program_name; + +void error_sys(const char *format, ...) { + va_list ap; + fprintf(stderr, "%s: ", program_name); + va_start(ap, format); + vfprintf(stderr, format, ap); + va_end(ap); + fprintf(stderr, "%s\n", strerror(errno)); +} + +void usage(void) { + fprintf(stderr, "usage: %s [contents]\n" + "type is one of data256, data512, data1024, prog1024\n", + program_name); +} + +#define BUF_SIZE 4096 + +int main(int argc, char *argv[]) { + int i, size, fill, done; + char *fname; + FILE *fp, *contents_fp; + unsigned char buf[BUF_SIZE]; + + program_name = argv[0]; + if (argc < 3) { + usage(); + return 1; + } + + fname = argv[1]; + + fp = fopen(fname, "wb"); + if (!fp) { + error_sys("%s: ", fname); + return 1; + } + + fill = 0xff; + if (!strcmp(argv[2], "data256")) + size = 2112 * (1 << 17); + else if (!strcmp(argv[2], "data512")) + size = 2112 * (1 << 18); + else if (!strcmp(argv[2], "data1024")) + size = 2112 * (1 << 19); + else if (!strcmp(argv[2], "prog1024")) + size = 1024 * 1024; + else { + usage(); + return 1; + } + + if (argc >= 4) { + contents_fp = fopen(argv[3], "rb"); + if (!contents_fp) { + error_sys("%s: ", argv[3]); + return 1; + } + } else + contents_fp = NULL; + + done = 0; + while (done < size) { + int l = (size - done > BUF_SIZE) ? BUF_SIZE : size - done; + + memset(buf, fill, l); + if (contents_fp) { + if (fread(buf, 1, l, contents_fp) < l) { + fclose(contents_fp); + contents_fp = NULL; + } + } + + if (fwrite(buf, l, 1, fp) < 1) { + error_sys("%s: ", fname); + return 1; + } + done += l; + } + + if (fclose(fp) == EOF) + error_sys("%s: ", fname); + + return 0; +} Index: utils/emuriver/src/Makefile.am =================================================================== --- utils/emuriver/src/Makefile.am (revision 0) +++ utils/emuriver/src/Makefile.am (revision 0) @@ -0,0 +1,16 @@ +SUBDIRS = common flashimgtool + +bin_PROGRAMS = emuriver make_flash_img +emuriver_SOURCES = main.c cpu.c memory.c trace.c hardware.c log.c \ + gdb.c lcd.c \ + trainer.c event.c usb.c cpu.h emuriver.h event.h gdb.h hardware.h \ + lcd.h log.h memory.h trace.h trainer.h usb.h ui.c ui.h flash.c \ + flash.h profile.c profile.h + +EXTRA_emuriver_SOURCES = uicurses.c uisdl.c +emuriver_LDADD = @CURSES_LIB@ @SDL_LIBS@ @UI_OBJS@ +emuriver_DEPENDENCIES = @UI_OBJS@ +make_flash_img_SOURCES = make_flash_img.c + +uisdl.o: uisdl.c + $(COMPILE) $(SDL_CFLAGS) -c $(srcdir)/uisdl.c Index: utils/emuriver/src/usb.c =================================================================== --- utils/emuriver/src/usb.c (revision 0) +++ utils/emuriver/src/usb.c (revision 0) @@ -0,0 +1,441 @@ +/* iRiver iFP 7XX Emulator + Copyright (C) 2005 Tomasz Malesinski + + 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 */ + +#include + +#include "usb.h" +#include "log.h" + +struct reg_structure { + int bit; + int n; + char *name; +}; + +struct reg_structure mode_structure[] = { + {0, 1, "SOFTCT"}, + {1, 1, "PWRON"}, + {2, 1, "WKUPCS"}, + {3, 1, "GLINTENA"}, + {4, 1, "SFRESET"}, + {5, 1, "GOSUSP"}, + {6, 1, "SNDRSU"}, + {7, 1, "CLKAON"}, + {9, 1, "DMACLKON"}, + {-1, -1, NULL} +}; + +struct reg_structure inten_structure[] = { + {0, 1, "BRST"}, + {1, 1, "SOF"}, + {2, 1, "PSOF"}, + {3, 1, "SUSP"}, + {4, 1, "RESM"}, + {5, 1, "HS_STA"}, + {6, 1, "DMA"}, + {7, 1, "VBUS"}, + {8, 1, "EP0SETUP"}, + {10, 1, "EP0RX"}, + {11, 1, "EP0TX"}, + {12, 1, "EP1RX"}, + {13, 1, "EP1TX"}, + {14, 1, "EP2RX"}, + {15, 1, "EP2TX"}, + {16, 1, "EP3RX"}, + {17, 1, "EP3TX"}, + {18, 1, "EP4RX"}, + {19, 1, "EP4TX"}, + {20, 1, "EP5RX"}, + {21, 1, "EP5TX"}, + {22, 1, "EP6RX"}, + {23, 1, "EP6TX"}, + {24, 1, "EP7RX"}, + {25, 1, "EP7TX"}, + {-1, -1, NULL} +}; + +struct reg_structure intconf_structure[] = { + {0, 1, "INTPOL"}, + {1, 1, "INTLVL"}, + {2, 2, "DDBGMODOUT"}, + {4, 2, "DDBGMODIN"}, + {6, 2, "CDBGMOD"}, + {-1, -1, NULL} +}; + +struct reg_structure epindex_structure[] = { + {0, 1, "DIR"}, + {1, 4, "ENDPIDX"}, + {5, 1, "EP0SETUP"}, + {-1, -1, NULL} +}; + +struct reg_structure ctrl_structure[] = { + {0, 1, "STALL"}, + {1, 1, "STATUS"}, + {2, 1, "DSEN"}, + {3, 1, "VENDP"}, + {4, 1, "CLBUF"}, + {-1, -1, NULL} +}; + +struct reg_structure maxpacketsize_structure[] = { + {0, 11, "FFOSZ"}, + {11, 2, "NTRANS"}, + {-1, -1, NULL} +}; + +struct reg_structure type_structure[] = { + {0, 2, "ENDTYP"}, + {2, 1, "DBLBUF"}, + {3, 1, "ENABLE"}, + {4, 1, "NOEMPKT"}, + {-1, -1, NULL} +}; + +static void bit_values(char *s, uint32 val, struct reg_structure *reg) { + int first = 1; + int n; + while (reg->bit >= 0) { + if (first) + first = 0; + else + *s++ = ' '; + sprintf(s, "%s=%x%n", + reg->name, (val >> reg->bit) & ((1 << reg->n) - 1), &n); + s += n; + reg++; + } + *s = 0; +} + +static int fill_in_fifo(struct usb *usb, struct usb_in_fifo *in_fifo) { + if (in_fifo->len > 0) + return USB_ERR_BUFFER_FULL; + + in_fifo->ptr = 0; + in_fifo->len = usb->in_buf_ptr; + memcpy(in_fifo->data, usb->in_buf, usb->in_buf_ptr); + usb->in_buf_ptr = 0; + return 0; +} + +static int in_fifo_get_byte(struct usb_in_fifo *in_fifo) { + if (in_fifo->len) { + int r = in_fifo->data[in_fifo->ptr++]; + if (in_fifo->ptr == in_fifo->len) + in_fifo->len = 0; + return r; + } else + return 0; +} + +static int in_fifo_get_half_word(struct usb_in_fifo *in_fifo) { + int l, h; + l = in_fifo_get_byte(in_fifo); + h = in_fifo_get_byte(in_fifo); + return (h << 8) | l; +} + +struct usb *create_usb(void) { + struct usb *usb; + + usb = xmalloc(sizeof(struct usb)); + if (!usb) + return NULL; + + usb_reset(usb); + + return usb; +} + +void free_usb(struct usb *usb) { + if (usb) free(usb); +} + +void usb_reset(struct usb *usb) { + int i; + + usb->mode_reg = 0; + usb->inten_reg = 0; + usb->intconf_reg = 0xfc; + usb->index_reg = 0; + + for (i = 0; i < 8; i++) { + usb->endpoint[i].ctrl = 0; + usb->endpoint[i].buflen = 0; + usb->endpoint[i].maxpacketsize = 0; + usb->endpoint[i].type = 0; + usb->endpoint[i].in_fifo.len = 0; + usb->endpoint[i].out_ptr = 0; + } + + usb->in_buf_ptr = 0; +} + +static int usb_dir(struct usb *usb) { + return usb->index_reg & 1; +} + +static int usb_setup(struct usb *usb) { + return (usb->index_reg >> 5) & 1; +} + +static int endpoint_index(struct usb *usb) { + int n = (usb->index_reg >> 1) & 1; + return (n > 7) ? 7 : n; +} + +static struct usb_endpoint *endpoint(struct usb *usb) { + return usb->endpoint + endpoint_index(usb); +} + +uint32 usb_read_word(void *data, uint32 adr) { + struct usb *usb = data; + + switch (adr & 0xffff) { + case 0x14: + logmsg(LOG_USB, 10, "usb: read interrupt enable\n"); + return usb->inten_reg; + case 0x18: + logmsg(LOG_USB, 10, "usb: read interrupt\n"); + return usb->int_status; + case 0x70: + logmsg(LOG_USB, 10, "usb: read id\n"); + return 0x158230; + default: + logmsg(LOG_USB, 5, "usb: read word from %x\n", adr); + return 0; + } +} + +void usb_write_word(void *data, uint32 adr, uint32 val) { + char tmp[200]; + struct usb *usb = data; + + switch (adr & 0xffff) { + case 0x14: + usb->inten_reg = val; + bit_values(tmp, val, inten_structure); + logmsg(LOG_USB, 10, "usb: write %x to inten (%s)\n", val, tmp); + break; + case 0x18: + logmsg(LOG_USB, 10, "usb: write %x to interrupt\n", val); + usb->int_status &= ~val; + break; + default: + logmsg(LOG_USB, 5, "usb: write word %x to %x\n", val, adr); + } +} + +uint32 usb_read_half_word(void *data, uint32 adr) { + struct usb *usb = data; + + switch (adr & 0xffff) { + case 0x04: + logmsg(LOG_USB, 10, "usb: read from maxpacketsize\n"); + return endpoint(usb)->maxpacketsize; + case 0x8: + logmsg(LOG_USB, 10, "usb: read from endpoint type\n"); + return endpoint(usb)->type; + case 0x0c: + logmsg(LOG_USB, 10, "usb: read from mode reg\n"); + return usb->mode_reg; + case 0x1c: + logmsg(LOG_USB, 10, "usb: read from buflen\n"); + if (usb_setup(usb)) + return usb->setup_in_fifo.len; + else if (usb_dir(usb) == 0) + return endpoint(usb)->in_fifo.len; + else + return endpoint(usb)->buflen; + case 0x20: + logmsg(LOG_USB, 10, "usb: read from data port\n"); + if (usb_setup(usb)) + return in_fifo_get_half_word(&usb->setup_in_fifo); + else if (usb_dir(usb) == 0) + return in_fifo_get_half_word(&endpoint(usb)->in_fifo); + else + return 0; + default: + logmsg(LOG_USB, 5, "usb: read half word from %x\n", adr); + return 0; + } +} + +static void usb_send_packet(struct usb *usb) { + struct usb_endpoint *ep = endpoint(usb); + char tmp[USB_BUF_SIZE * 3 + 1]; + int i; + + for (i = 0; i < ep->out_ptr; i++) + sprintf(tmp + 3 * i, " %02x", ep->out_buf[i]); + tmp[3 * ep->out_ptr] = 0; + logmsg(LOG_USB, 5, "usb: sending packet:%s\n", tmp); + + usb->int_status |= (1 << (11 + endpoint_index(usb) * 2)); + ep->out_ptr = 0; +} + +static void usb_write_to_fifo(struct usb *usb, uint32 val) { + struct usb_endpoint *ep = endpoint(usb); + ep->out_buf[ep->out_ptr++] = val & 0xff; + if (ep->out_ptr >= ep->buflen) + usb_send_packet(usb); + else { + ep->out_buf[ep->out_ptr++] = (val >> 8) & 0xff; + if (ep->out_ptr >= ep->buflen) + usb_send_packet(usb); + } +} + +void usb_write_half_word(void *data, uint32 adr, uint32 val) { + struct usb *usb = data; + char tmp[100]; + + switch (adr & 0xffff) { + case 0x04: + endpoint(usb)->maxpacketsize = val; + /* TODO reinitialize buflens */ + bit_values(tmp, val, maxpacketsize_structure); + logmsg(LOG_USB, 10, "usb: maxpacketsize set to %x (%s)\n", val, tmp); + break; + case 0x08: + endpoint(usb)->type = val; + bit_values(tmp, val, type_structure); + logmsg(LOG_USB, 10, "usb: write %x to endpoint type (%s)\n", val, tmp); + break; + case 0x0c: + usb->mode_reg = val; + bit_values(tmp, val, mode_structure); + logmsg(LOG_USB, 10, "usb: mode reg set to %x (%s)\n", val, tmp); + break; + case 0x1c: + endpoint(usb)->buflen = val; + logmsg(LOG_USB, 10, "usb: write %x to buflen\n", val); + break; + case 0x20: + logmsg(LOG_USB, 10, "usb: write %x to data port\n", val); + usb_write_to_fifo(usb, val); + break; + case 0x7c: + if (val == 0xaa37) + logmsg(LOG_USB, 10, "usb: device unlocked\n"); + else + logmsg(LOG_USB, 5, "usb: invalid vaule written to unlock\n"); + break; + default: + logmsg(LOG_USB, 5, "usb: write half word %x to %x\n", val, adr); + } +} + +uint8 usb_read(void *data, uint32 adr) { + struct usb *usb = data; + + switch (adr & 0xffff) { + case 0x10: + logmsg(LOG_USB, 10, "usb: read from interrupt configuration\n"); + return usb->intconf_reg; + case 0x1e: + logmsg(LOG_USB, 10, "usb: read from buffer status\n"); + return 0; + case 0x28: + logmsg(LOG_USB, 10, "usb: read from control function\n"); + return endpoint(usb)->ctrl; + default: + logmsg(LOG_USB, 5, "usb: read byte from %x\n", adr); + return 0; + } +} + +void usb_write(void *data, uint32 adr, uint8 val) { + struct usb *usb = data; + char tmp[100]; + + switch (adr & 0xffff) { + case 0x0: + logmsg(LOG_USB, 10, "usb: write %x to address\n", val); + break; + case 0x10: + usb->intconf_reg = val; + bit_values(tmp, val, intconf_structure); + logmsg(LOG_USB, 10, "usb: write %x to intconf (%s)\n", val, tmp); + break; + case 0x28: + endpoint(usb)->ctrl = val & ~0x18; + if (val & 0x10) { + if (usb_setup(usb)) + usb->setup_in_fifo.len = 0; + else + endpoint(usb)->in_fifo.len = 0; + } + if (val & 0x80) { + + } + bit_values(tmp, val, ctrl_structure); + logmsg(LOG_USB, 10, "usb: write %x to control function (%s)\n", val, tmp); + break; + case 0x2c: + usb->index_reg = val; + bit_values(tmp, val, epindex_structure); + logmsg(LOG_USB, 10, "usb: write %x to endpoint index (%s)\n", val, tmp); + break; + default: + logmsg(LOG_USB, 5, "usb: write byte %x to %x\n", val, adr); + } +} + +void usb_receive_byte(struct usb *usb, uint8 byte) { + if (usb->in_buf_ptr < USB_BUF_SIZE) + usb->in_buf[usb->in_buf_ptr++] = byte; +} + +int usb_bus_reset(struct usb *usb) { + usb->int_status |= 1; + return 0; +} + +int usb_suspend(struct usb *usb) { + usb->int_status |= 8; + return 0; +} + +int usb_resume(struct usb *usb) { + usb->int_status |= 0x10; + return 0; +} + +int usb_hs_stat(struct usb *usb) { + usb->int_status |= 0x20; + return 0; +} + +int usb_rcv_setup(struct usb *usb) { + int r; + r = fill_in_fifo(usb, &(usb->setup_in_fifo)); + if (r < 0) return r; + usb->int_status |= 0x100; + return 0; +} + +int usb_rcv_data(struct usb *usb, int e) { + int r; + r = fill_in_fifo(usb, &(usb->endpoint[e].in_fifo)); + if (r < 0) return r; + usb->int_status |= (1 << (10 + 2 * e)); + return 0; +} Index: utils/emuriver/src/gdb.c =================================================================== --- utils/emuriver/src/gdb.c (revision 0) +++ utils/emuriver/src/gdb.c (revision 0) @@ -0,0 +1,800 @@ +/* iRiver iFP 7XX Emulator + Copyright (C) 2005 Tomasz Malesinski + + 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 */ + +#include +#include +#include +#include +#include +#include + +#include "emuriver.h" +#include "cpu.h" +#include "hardware.h" +#include "log.h" +#include "ui.h" +#include "usb.h" + +#define GDB_PORT 5555 + +static const char hexchars[] = "0123456789abcdef"; +static int gdb_socket = -1, client_fd = -1; +static int last_signal; + +static int hex(char ch) { + if ((ch >= 'a') && (ch <= 'f')) + return ch - 'a' + 10; + if ((ch >= '0') && (ch <= '9')) + return ch - '0'; + if ((ch >= 'A') && (ch <= 'F')) + return ch - 'A' + 10; + return -1; +} + +static void hex_byte(char *s, int byte) { + s[0] = hexchars[(byte >> 4) & 0xf]; + s[1] = hexchars[byte & 0xf]; +} + +static void hex_word(char *s, uint32 val) { + int i; + for (i = 0; i < 4; i++) + hex_byte(s + i * 2, (val >> (i * 8)) & 0xff); +} + +static void hex_string(char *d, char *s) { + while (*s) { + hex_byte(d, *s++); + d += 2; + } + *d = 0; +} + +static int get_hex_byte(char *s) { + return (hex(s[0]) << 4) + hex(s[1]); +} + +static uint32 get_hex_word(char *s) { + int i; + uint32 r = 0; + for (i = 3; i >= 0; i--) + r = (r << 8) + get_hex_byte(s + i * 2); + return r; +} + +static void reply_error(int n, char *reply) { + reply[0] = 'E'; + hex_byte(reply + 1, n); + reply[3] = 0; +} + +static void reply_signal(int n, char *reply) { + reply[0] = 'S'; + hex_byte(reply + 1, n); + reply[3] = 0; +} + +static void reply_watch(char *type, char *reply) { + sprintf(reply, "T%02x%s:%08x;", 5, type, cpu->break_addr); +} + +static void reply_ok(char *reply) { + strcpy(reply, "OK"); +} + +static int open_gdb_socket(void) { + struct sockaddr_in name; + int tmp; + + gdb_socket = socket(PF_INET, SOCK_STREAM, 0); + if (gdb_socket < 0) { + error_sys("socket: "); + return -1; + } + + tmp = 1; + setsockopt (gdb_socket, SOL_SOCKET, SO_REUSEADDR, &tmp, + sizeof (tmp)); + setsockopt (gdb_socket, SOL_TCP, TCP_NODELAY, &tmp, + sizeof (tmp)); + + name.sin_family = AF_INET; + name.sin_port = htons(GDB_PORT); + name.sin_addr.s_addr = htonl(INADDR_ANY); + if (bind(gdb_socket, (struct sockaddr *)&name, sizeof(name)) < 0) { + error_sys("bind: "); + close(gdb_socket); + return -1; + } + + if (listen(gdb_socket, 1) < 0) { + error_sys("listen: "); + close(gdb_socket); + return -1; + } + + return 0; +} + +static void close_gdb_socket(void) { + if (gdb_socket >= 0) { + close(gdb_socket); + gdb_socket = -1; + } +} + +static int wait_for_client(void) { + struct sockaddr_in name; + int fd, size; + + size = sizeof(name); + client_fd = accept(gdb_socket, (struct sockaddr *)&name, &size); + + return client_fd; +} + +static void close_client_socket(void) { + if (client_fd >= 0) { + close(client_fd); + client_fd = -1; + } +} + +static int socket_read(int fd, unsigned char *buf, int len) { + int r; + int done = 0; + while (done < len) { + r = read(fd, buf + done, len - done); + if (r == -1) { + if (errno != EINTR && errno != EAGAIN) + return -1; + } else + done += r; + } + return 0; +} + +static int socket_get_byte(int fd) { + unsigned char buf; + if (socket_read(fd, &buf, 1) < 0) + return -1; + else + return buf; +} + +static int socket_write(int fd, unsigned char *buf, int len) { + int r; + int done = 0; + while (done < len) { + r = write(fd, buf + done, len - done); + if (r == -1) { + if (errno != EINTR && errno != EAGAIN) + return -1; + } else + done += r; + } + return 0; +} + +static int socket_put_byte(int fd, int byte) { + unsigned char buf = byte; + return socket_write(fd, &buf, 1); +} + +static int socket_try_get_byte(int fd) { + unsigned char buf; + int oldflags, newflags; + int r; + + oldflags = fcntl(fd, F_GETFL, 0); + if (oldflags == -1) + return -1; + newflags = oldflags | O_NONBLOCK; + if (oldflags != newflags) { + r = fcntl(fd, F_SETFL, newflags); + if (r == -1) + return -1; + } + + r = read(fd, &buf, 1); + + if (oldflags != newflags) + fcntl(fd, F_SETFL, oldflags); + + if (r != 1) + return -1; + else + return buf; +} + +static int get_packet(char *buf, int len) { + int count, checksum, escaped; + int ch; + + while (1) { + do { + ch = socket_get_byte(client_fd); + if (ch == -1) return -1; + } while (ch != '$'); + + checksum = 0; + count = 0; + escaped = 0; + while (count < len) { + ch = socket_get_byte(client_fd); + if (ch == -1) + return -1; + if (!escaped) { + if (ch == '$') { + checksum = 0; + count = 0; + } else if (ch == '#') + break; + else if (ch == 0x7d) { + escaped = 1; + checksum += ch; + } else { + checksum += ch; + buf[count] = ch; + count++; + } + } else { + escaped = 0; + checksum += ch; + buf[count] = ch ^ 0x20; + count++; + } + } + + buf[count] = 0; + + if (ch == '#') { + int rchksum; + + ch = socket_get_byte(client_fd); + rchksum = hex(ch) << 4; + ch = socket_get_byte(client_fd); + rchksum += hex(ch); + + if ((checksum & 0xff) != rchksum) + socket_put_byte(client_fd, '-'); + else { + socket_put_byte(client_fd, '+'); + return count; + } + } + } +} + +static int put_packet(char *buf) { + int i, checksum; + int ch; + char tmp[3]; + + do { + socket_put_byte(client_fd, '$'); + + checksum = 0; + for (i = 0; buf[i]; i++) + checksum += buf[i]; + + socket_write(client_fd, buf, i); + + tmp[0] = '#'; + hex_byte(tmp + 1, checksum & 0xff); + socket_write(client_fd, tmp, 3); + + ch = socket_get_byte(client_fd); + + } while (ch != '+'); +} + +static void g_reply(char *buf) { + int i; + char *p; + + p = buf; + for (i = 0; i < 16; i++) { + hex_word(p, cpu->reg[i]); + p += 8; + } + + for (i = 0; i < 8; i++) { + memset(p, '0', 16); + p += 16; + } + + hex_word(p, 0); + p += 8; + hex_word(p, cpu->cpsr); + p[8] = 0; +} + +static void cmd_get_register(char *args, char *reply) { + int r; + + if (sscanf(args, "%x", &r) != 1) { + reply_error(0, reply); + return; + } + + if (r >= 0 && r < 16) { + hex_word(reply, cpu->reg[r]); + reply[8] = 0; + } else if (r == 25) { + hex_word(reply, cpu->cpsr); + reply[8] = 0; + } else { + hex_word(reply, 0); + reply[8] = 0; + } +} + +static void cmd_set_register(char *args, char *reply) { + int r, p; + uint32 v; + + p = -1; + sscanf(args, "%x=%n", &r, &p); + if (p == -1) { + reply_error(0, reply); + return; + } + + v = get_hex_word(args + p); + if (r >= 0 && r < 16) + cpu->reg[r] = v; + else if (r == 25) + cpu->cpsr = v; + reply_ok(reply); +} + +static void cmd_set_registers(char *args, char *reply) { + char *p; + int i, len; + + len = strlen(args); + + p = args; + for (i = 0; i < 16 && len >= (i + 1) * 8; i++) { + cpu->reg[i] = get_hex_word(p); + p += 8; + } + + if (len >= 16 * 8 + 8 * 16 + 2 * 8) { + p += 8 * 16 + 8; + cpu->cpsr = get_hex_word(p); + } + + reply_ok(reply); +} + +static cmd_get_memory(char *args, char *reply) { + uint32 addr, len; + int i; + + if (sscanf(args, "%x,%x", &addr, &len) != 2) { + reply_error(0, reply); + return; + } + + if (len > 8000) { + reply_error(1, reply); + return; + } + + for (i = 0; i < len; i++) + hex_byte(reply + i * 2, memory_read(cpu->mem, addr + i, NULL, 0)); + reply[len * 2] = 0; +} + +static cmd_put_memory(char *args, char *reply) { + uint32 addr, len; + int i, pos; + + pos = -1; + sscanf(args, "%x,%x:%n", &addr, &len, &pos); + if (pos == -1) { + reply_error(0, reply); + return; + } + + for (i = 0; i < len; i++) + memory_write(cpu->mem, addr + i, + get_hex_byte(args + pos + i * 2), NULL, 0); + + reply_ok(reply); +} + +static void cmd_put_memory_binary(char *args, char *reply) { + unsigned long addr, len, i; + int pos; + + pos = -1; + sscanf(args, "%lx,%lx:%n", &addr, &len, &pos); + if (pos == -1) { + reply_error(0, reply); + return; + } + + for (i = 0; i < len; i++) + memory_write(cpu->mem, addr + i, args[pos + i], NULL, 0); + + reply_ok(reply); +} + +static void parse_continue_args(char *args) { + int sig; + uint32 addr; + + if (sscanf(args, "%x;%x", &sig, &addr) == 2) { + cpu->reg[15] = addr; + } else if (sscanf(args, "%x", &addr) == 1) { + cpu->reg[15] = addr; + } +} + +static int gdb_go_handler(void) { + int r; + + r = socket_try_get_byte(client_fd); + return (r == 3) ? CPU_STOP_TERMINATE : 0; +} + +static int cmd_go(int n, char *args, char *reply) { + int r; + parse_continue_args(args); + + r = go(n, gdb_go_handler, 1000); + + switch (r) { + case CPU_STOP_QUIT: + strcpy(reply, "W00"); + return 1; + case CPU_STOP_TERMINATE: + last_signal = 2; + reply_signal(2, reply); + break; + case CPU_STOP_ILLEGAL: + last_signal = 4; + reply_signal(4, reply); + break; + case CPU_STOP_RWATCH: + last_signal = 5; + reply_watch("rwatch", reply); + break; + case CPU_STOP_WWATCH: + last_signal = 5; + reply_watch("watch", reply); + break; + case CPU_STOP_AWATCH: + last_signal = 5; + reply_watch("awatch", reply); + break; + default: + last_signal = 5; + reply_signal(5, reply); + break; + } + return 0; +} + +static void do_set_break(int type, uint32 addr, char *reply) { + if (cpu_insert_break(cpu, type, addr) < 0) { + reply_error(1, reply); + return; + } else + reply_ok(reply); +} + +static void cmd_set_breakpoint(char *args, char *reply) { + int type, len; + uint32 addr; + + if (sscanf(args, "%d,%x,%x", &type, &addr, &len) != 3) { + reply_error(0, reply); + return; + } + + switch (type) { + case 1: + do_set_break(CPU_BRK_BREAK, addr, reply); + reply_ok(reply); + break; + + case 2: + do_set_break(CPU_BRK_WWATCH, addr, reply); + reply_ok(reply); + break; + + case 3: + do_set_break(CPU_BRK_RWATCH, addr, reply); + reply_ok(reply); + break; + + case 4: + do_set_break(CPU_BRK_AWATCH, addr, reply); + reply_ok(reply); + break; + + default: + reply[0] = 0; + break; + } +} + +static void cmd_remove_breakpoint(char *args, char *reply) { + int type, len; + uint32 addr; + + if (sscanf(args, "%d,%x,%x", &type, &addr, &len) != 3) { + reply_error(0, reply); + return; + } + + switch (type) { + case 1: + cpu_remove_break(cpu, CPU_BRK_BREAK, addr); + reply_ok(reply); + break; + + case 2: + cpu_remove_break(cpu, CPU_BRK_WWATCH, addr); + reply_ok(reply); + break; + + case 3: + cpu_remove_break(cpu, CPU_BRK_RWATCH, addr); + reply_ok(reply); + break; + + case 4: + cpu_remove_break(cpu, CPU_BRK_AWATCH, addr); + reply_ok(reply); + break; + + default: + reply[0] = 0; + break; + } +} + +static void reply_invalid_cmd(char *reply) { + hex_string(reply, "Invalid command\n"); +} + +static void usb_cmd_reply(char *reply, int r) { + switch (r) { + case USB_ERR_ENDPOINT_DISABLED: + hex_string(reply, "Endpoint disabled\n"); + break; + case USB_ERR_BUFFER_FULL: + hex_string(reply, "Buffer full\n"); + break; + case 0: + reply_ok(reply); + break; + default: + hex_string(reply, "Unknown error\n"); + break; + } +} + +static void remote_cmd(char *cmd, char *reply) { + char name[30]; + int p; + + logmsg(LOG_GDB, 5, "gdb: remote command %s\n", cmd); + p = -1; + sscanf(cmd, "%29s%n", name, &p); + + if (p == -1) { + reply_invalid_cmd(reply); + return; + } + + if (!strcmp("usb_connected", name)) { + int v; + if (sscanf(cmd + p, "%d", &v) != 1) + reply_invalid_cmd(reply); + else { + hardware->usb_connected = (v != 0); + reply_ok(reply); + } + + } else if (!strcmp("usb_receive", name)) { + char *s = cmd + p; + while (1) { + while (isspace(*s)) s++; + if (isxdigit(s[0]) && isxdigit(s[1])) { + usb_receive_byte(hardware->usb, get_hex_byte(s)); + s += 2; + } else + break; + } + reply_ok(reply); + + } else if (!strcmp("usb_rcv_setup", name)) { + int r = usb_rcv_setup(hardware->usb); + usb_cmd_reply(reply, r); + + } else if (!strcmp("usb_bus_reset", name)) { + int r = usb_bus_reset(hardware->usb); + usb_cmd_reply(reply, r); + + } else if (!strcmp("usb_suspend", name)) { + int r = usb_suspend(hardware->usb); + usb_cmd_reply(reply, r); + + } else if (!strcmp("usb_resume", name)) { + int r = usb_resume(hardware->usb); + usb_cmd_reply(reply, r); + + } else if (!strcmp("usb_hs_stat", name)) { + int r = usb_hs_stat(hardware->usb); + usb_cmd_reply(reply, r); + + } else if (!strcmp("usb_rcv_data", name)) { + int e; + if (sscanf(cmd + p, "%d", &e) != 1 || e < 0 || e > 7) + reply_invalid_cmd(reply); + else { + int r = usb_rcv_data(hardware->usb, e); + usb_cmd_reply(reply, r); + } + + } else if (!strcmp("history", name)) { + char buf[CPU_HISTORY_SIZE * 10 + 1]; + cpu_history_to_string(cpu, buf); + fprintf(stderr, "%s\n", buf); + reply_ok(reply); + + } else if (!strcmp("key_down", name)) { + int k; + if (sscanf(cmd + p, "%d", &k) != 1 || k < 0 || k > 9) + reply_invalid_cmd(reply); + else { + ui_set_key_override(k, 1); + reply_ok(reply); + } + + } else if (!strcmp("key_up", name)) { + int k; + if (sscanf(cmd + p, "%d", &k) != 1 || k < 0 || k > 9) + reply_invalid_cmd(reply); + else { + ui_set_key_override(k, 0); + reply_ok(reply); + } + + } else + hex_string(reply, "Unrecognized command\n"); +} + +static void cmd_query(char *args, char *reply) { + if (!strncmp(args, "Rcmd,", 5)) { + int i = 0; + char *s = args + 5; + char cmd[200]; + while (isxdigit(s[0]) && isxdigit(s[1]) && i < sizeof(cmd) - 1) { + cmd[i++] = get_hex_byte(s); + s += 2; + } + cmd[i] = 0; + remote_cmd(cmd, reply); + } else + reply[0] = 0; +} + +void gdb_target(void) { + char packet_buf[16384]; + char reply_buf[16384]; + int quit = 0, no_reply; + + tick = 0; + + if (open_gdb_socket() < 0) + return; + + last_signal = 5; + while (!quit) { + if (wait_for_client() < 0) + break; + + while (!quit) { + if (get_packet(packet_buf, sizeof(packet_buf) - 1) < 0) { + close_client_socket(); + break; + } + + logmsg(LOG_GDB, 15, "gdb: received %s\n", packet_buf); + no_reply = 0; + switch (packet_buf[0]) { + case '?': + reply_signal(last_signal, reply_buf); + break; + + case 'p': + cmd_get_register(packet_buf + 1, reply_buf); + break; + + case 'P': + cmd_set_register(packet_buf + 1, reply_buf); + break; + + case 'g': + g_reply(reply_buf); + break; + + case 'G': + cmd_set_registers(packet_buf + 1, reply_buf); + break; + + case 'm': + cmd_get_memory(packet_buf + 1, reply_buf); + break; + + case 'M': + cmd_put_memory(packet_buf + 1, reply_buf); + break; + + case 'X': + cmd_put_memory_binary(packet_buf + 1, reply_buf); + break; + + case 'q': + cmd_query(packet_buf + 1, reply_buf); + break; + + case 'c': + if (cmd_go(0, packet_buf + 1, reply_buf)) + quit = 1; + break; + + case 's': + if (cmd_go(1, packet_buf + 1, reply_buf)) + quit = 1; + break; + + case 'Z': + cmd_set_breakpoint(packet_buf + 1, reply_buf); + break; + + case 'z': + cmd_remove_breakpoint(packet_buf + 1, reply_buf); + break; + + case 'k': + quit = 1; + no_reply = 1; + break; + + default: + reply_buf[0] = 0; + } + + if (!no_reply) { + logmsg(LOG_GDB, 15, "gdb: replying %s\n", reply_buf); + put_packet(reply_buf); + } + } + + close_client_socket(); + } + + close_gdb_socket(); +} Index: utils/emuriver/src/flash.c =================================================================== --- utils/emuriver/src/flash.c (revision 0) +++ utils/emuriver/src/flash.c (revision 0) @@ -0,0 +1,264 @@ +/* iRiver iFP 7XX Emulator + Copyright (C) 2006 Tomasz Malesinski + + 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 */ + +#include +#include + +#include "flash.h" +#include "log.h" + +static int flash_read_page_oob(struct flash *flash, int page) { + flash->only_oob = 1; + flash->page = page; + if (fseek(flash->fp, flash->offset + page * 64, SEEK_SET) == -1) + return -1; + if (fread(flash->reg + 2048, 1, 64, flash->fp) != 64) return -1; + return 0; +} + +static inline int flash_n_pages(struct flash *flash) { + switch (flash->model) { + case FLASH_256_8: + return 128 * 1024; + case FLASH_512_8: + return 256 * 1024; + case FLASH_1024_8: + return 512 * 1024; + default: + return 0; + } +} + +static inline int flash_row_mask(struct flash *flash) { + switch (flash->model) { + case FLASH_256_8: + return 1; + case FLASH_512_8: + return 3; + case FLASH_1024_8: + return 7; + default: + return 0; + } +} + +static inline int flash_id(struct flash *flash) { + switch (flash->model) { + case FLASH_256_8: + return 0xda; + case FLASH_512_8: + return 0xdc; + case FLASH_1024_8: + return 0xdf; + } +} + +static int flash_read_page_rest(struct flash *flash) { + if (flash->only_oob) { + if (fseek(flash->fp, + flash->offset + flash->page * 2048 + flash_n_pages(flash) * 64, + SEEK_SET) == -1) + return -1; + if (fread(flash->reg, 1, 2048, flash->fp) != 2048) return -1; + } + flash->only_oob = 0; +} + +static int flash_read_page_byte(struct flash *flash, int ptr) { + if (ptr < 2048) + flash_read_page_rest(flash); + return flash->reg[ptr]; +} + +static int flash_write_page(struct flash *flash, int page) { + if (fseek(flash->fp, flash->offset + page * 64, SEEK_SET) == -1) + return -1; + if (fwrite(flash->reg + 2048, 1, 64, flash->fp) != 64) return -1; + if (fseek(flash->fp, + flash->offset + page * 2048 + flash_n_pages(flash) * 64, + SEEK_SET) == -1) + return -1; + if (fwrite(flash->reg, 1, 2048, flash->fp) != 2048) return -1; + return 0; +} + +uint8 flash_read(struct flash *flash, int adr) { + uint8 r; + switch (adr & 0xc) { + case 0: + if (flash->ptr >= 2112) + flash->ptr = 0; + r = flash_read_page_byte(flash, flash->ptr); + flash->ptr++; + logmsg(LOG_FLASH, 20, "flash: read %x from %x\n", r, adr); + return r; + default: + logmsg(LOG_FLASH, 5, "flash: read from %x\n", adr); + } + return ~0; +} + +static void flash_read_cmd(struct flash *flash) { + int i; + int col = flash->adr[0] | ((flash->adr[1] & 0xf) << 8); + int row = flash->adr[2] | (flash->adr[3] << 8) + | ((flash->adr[4] & flash_row_mask(flash)) << 16); + + logmsg(LOG_FLASH, 5, "flash: read, address %6x/%3x\n", row, col); + + flash_read_page_oob(flash, row); + + flash->ptr = col; +} + +static void flash_page_program(struct flash *flash) { + int i; + int row = flash->adr[2] | (flash->adr[3] << 8) + | ((flash->adr[4] & flash_row_mask(flash)) << 16); + + logmsg(LOG_FLASH, 5, "flash: program, address %6x\n", row); + + flash_read_page_rest(flash); + flash_write_page(flash, row); +} + +static void flash_block_erase(struct flash *flash) { + int row = flash->adr[0] | (flash->adr[1] << 8) + | ((flash->adr[2] & flash_row_mask(flash)) << 16); + int i; + + logmsg(LOG_FLASH, 5, "flash: op block erase, address %6x\n", row); + row &= ~0x3f; + + for (i = 0; i < 2112; i++) + flash->reg[i] = 0xff; + + for (i = 0; i < 64; i++) + flash_write_page(flash, row + i); +} + +void flash_write(struct flash *flash, int adr, uint8 val) { + int i; + switch (adr & 0xc) { + case 0: + flash_read_page_rest(flash); + if (flash->ptr >= 2112) + flash->ptr = 0; + flash->reg[flash->ptr] = val; + flash->ptr++; + logmsg(LOG_FLASH, 20, "flash: write %x to %x\n", val, adr); + break; + case 4: + flash->adr_ptr = 0; + logmsg(LOG_FLASH, 19, "flash: command %x\n", val); + + switch (val) { + case 0x90: + flash->cmd = val; + logmsg(LOG_FLASH, 9, "flash: read id\n"); + flash->reg[0] = 0xec; + flash->reg[1] = flash_id(flash); + flash->reg[2] = 0xff; + flash->reg[3] = 0x15; + flash->ptr = 0; + flash->only_oob = 0; + break; + case 0x70: + flash->cmd = val; + flash->reg[0] = 0xe0; + flash->ptr = 0; + flash->only_oob = 0; + break; + case 0x00: + case 0x05: + case 0x60: + case 0x80: + case 0x85: + flash->cmd = val; + break; + case 0x10: + flash_page_program(flash); + break; + case 0x30: + case 0x35: + flash_read_cmd(flash); + break; + case 0xd0: + flash_block_erase(flash); + break; + case 0xe0: + i = flash->adr[0] | ((flash->adr[1] & 0xf) << 8); + flash->ptr = i; + logmsg(LOG_FLASH, 10, "flash: read random, column %3x\n", i); + break; + default: + break; + } + break; + case 8: + logmsg(LOG_FLASH, 19, "flash: address %x\n", val); + if (flash->adr_ptr >= 5) + flash->adr_ptr = 0; + + flash->adr[flash->adr_ptr] = val; + flash->adr_ptr++; + + if (flash->cmd == 0x80 || flash->cmd == 0x85) { + flash->ptr = flash->adr[0] | ((flash->adr[1] & 0xf) << 8); + } + + if (flash->cmd == 0x80 && flash->adr_ptr == 5) { + int row = flash->adr[2] | (flash->adr[3] << 8) + | ((flash->adr[4] & flash_row_mask(flash)) << 16); + flash_read_page_oob(flash, row); + } + + break; + default: + logmsg(LOG_FLASH, 5, "flash: write %x to %x\n", val, adr); + } +} + +struct flash *create_flash(int model, char *fname, int offset) { + struct flash *flash; + + flash = xmalloc(sizeof(struct flash)); + if (!flash) + return NULL; + + flash->ptr = 0; + flash->only_oob = 0; + flash->model = model; + flash->fp = fopen(fname, "r+b"); + if (!flash->fp) { + error_sys("%s: ", fname); + free(flash); + return NULL; + } + flash->busy = 0; + flash->offset = offset; + return flash; +} + +void free_flash(struct flash *flash) { + if (flash) { + if (flash->fp) + fclose(flash->fp); + free(flash); + } +} + Index: utils/emuriver/src/hardware.c =================================================================== --- utils/emuriver/src/hardware.c (revision 0) +++ utils/emuriver/src/hardware.c (revision 0) @@ -0,0 +1,1496 @@ +/* iRiver iFP 7XX Emulator + Copyright (C) 2005 Tomasz Malesinski + + 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 */ + +#include +#include + +#include "memory.h" +#include "cpu.h" +#include "hardware.h" +#include "log.h" +#include "lcd.h" +#include "usb.h" +#include "flash.h" + +unsigned int tick; + +int tick_before(unsigned int a, unsigned int b) { + return (unsigned int)(b - a) < (1 << 30); +} + +static uint32 gpio_read(struct hardware *hardware, uint32 adr) { + int n = (adr >> 6) & 7; + int r = adr & 0x3f; + int i; + uint32 res; + + switch (r) { + case 0: + logmsg(LOG_GPIO, 20, "gpio(%d): read from register %x\n", n, r); + res = 0; + for (i = 31; i >= 0; i--) { + struct gpio_handler *h = &(hardware->gpio_handler[n][i]); + if (h->get) { + res = (res << 1) | (*(h->get))(h->data, n, i); + } else + res = (res << 1) | 1; + } + return res; + default: + logmsg(LOG_GPIO, 5, "gpio(%d): read from register %x\n", n, r); + return ~0; + } +} + +static void gpio_notify_handlers(struct hardware *hardware, + int port, uint32 old, uint32 new) { + int i; + for (i = 0; i < 32; i++) + if ((old ^ new) & (1 << i)) { + struct gpio_handler *h = &(hardware->gpio_handler[port][i]); + if (h->set) + (*h->set)(h->data, port, i, (new >> i) & 1); + } + +} + +int gpio_get_bit(struct hardware *hardware, int port, int bit) { + return (hardware->gpio_out[port] >> bit) & 1; +} + +void gpio_install_handler(struct hardware *hardware, int port, int bit, + void *data, + int (*get)(void *, int, int), + void (*set)(void *, int, int, int)) { + hardware->gpio_handler[port][bit].data = data; + hardware->gpio_handler[port][bit].get = get; + hardware->gpio_handler[port][bit].set = set; +} + +static void gpio_direction_changed(struct hardware *hardware, int port, + uint32 mask, uint32 new) { + int i; + for (i = 0; i < 32; i++) + if (mask & (1 << i)) + logmsg(LOG_GPIO, 10, "gpio: bit %d/%d set to %s\n", + port, i, (new & (1 << i)) ? "output" : "input"); +} + +static void gpio_write(struct hardware *hardware, uint32 adr, uint32 val) { + int n = (adr >> 6) & 7; + int r = adr & 0x3c; + uint32 old; + + switch (r) { + case 0x14: + old = hardware->gpio_out[n]; + hardware->gpio_out[n] |= val; + gpio_notify_handlers(hardware, + n, old, hardware->gpio_out[n]); + break; + case 0x18: + old = hardware->gpio_out[n]; + hardware->gpio_out[n] &= ~val; + gpio_notify_handlers(hardware, + n, old, hardware->gpio_out[n]); + break; + case 0x24: + hardware->gpio_dir[n] |= val; + gpio_direction_changed(hardware, n, + val, hardware->gpio_dir[n]); + break; + case 0x28: + hardware->gpio_dir[n] &= ~val; + gpio_direction_changed(hardware, n, + val, hardware->gpio_dir[n]); + break; + default: + logmsg(LOG_GPIO, 5, "gpio(%d): write %x to register %x\n", n, val, r); + } +} + +static int flash_ce[4] = {0x20, 0x02, 0x10, 0x08}; + +static int selected_flash(struct hardware *hardware) { + int i, r; + uint32 p5 = hardware->gpio_out[5]; + r = -1; + for (i = 0; i < 4; i++) + if (!(p5 & flash_ce[i])) { + if (r > 0) + logmsg(LOG_FLASH, 5, "flash: more than one chip selected\n"); + else + r = i; + } + return r; +} + +static int flash_get_busy(void *data, int port, int bit) { + struct hardware *hardware = data; + struct flash *flash; + int chip; + + chip = selected_flash(hardware); + if (chip == -1) + return 1; + + flash = hardware->flash[chip]; + if (!flash) + return 1; + + if (!flash->busy) + return 1; + + if (tick_before(flash->ready_tick, tick)) { + flash->busy = 0; + return 1; + } + + return 0; +} + +static uint32 prog_flash_read_half_word(void *data, uint32 adr, + struct profile *profile, + uint32 req_adr) { + struct prog_flash *flash = data; + logmsg(LOG_FW_FLASH, 10, "prog_flash: read from %x\n", adr); + adr = adr & 0xffffe; + + switch (flash->state) { + case 0: + return flash->content[adr] | (flash->content[adr + 1] << 8); + + case 0x90: + switch (adr) { + case 0: + return 0xbf; + case 2: + return 0x2781; + default: + return 0xffff; + } + default: + return 0xffff; + } +} + +static uint8 prog_flash_read_byte(void *data, uint32 adr, + struct profile *profile, uint32 req_adr) { + uint8 res; + if (adr & 1) + res = prog_flash_read_half_word(data, adr & ~1, profile, req_adr) >> 8; + else + res = prog_flash_read_half_word(data, adr, profile, req_adr) & 0xff; + logmsg(LOG_FW_FLASH, 10, "prog_flash: read byte %x\n", res); + return res; +} + +static uint32 prog_flash_read_word(void *data, uint32 adr, + struct profile *profile, uint32 req_adr) { + return prog_flash_read_half_word(data, adr & ~3, profile, req_adr) + | (prog_flash_read_half_word(data, (adr & ~3) + 2, + profile, req_adr) << 16); +} + +static int prog_flash_update(struct prog_flash *flash, int start, int size) { + if (fseek(flash->fp, start, SEEK_SET)) + return -1; + fwrite(flash->content + start, 1, size, flash->fp); + return 0; +} + +static void prog_flash_sector_erase(struct prog_flash *flash, int sector) { + sector = sector & 0xff; + logmsg(LOG_FW_FLASH, 5, "prog_flash: sector %x erase\n", sector); + memset(flash->content + sector * 4096, 0xff, 4096); + prog_flash_update(flash, sector * 4096, 4096); +} + +static void prog_flash_block_erase(struct prog_flash *flash, int block) { + block = block & 0xf; + logmsg(LOG_FW_FLASH, 5, "prog_flash: block %x erase\n", block); + memset(flash->content + block * 64 * 1024, 0xff, 64 * 1024); + prog_flash_update(flash, block * 64 * 1024, 64 * 1024); +} + +static void prog_flash_chip_erase(struct prog_flash *flash) { + logmsg(LOG_FW_FLASH, 5, "prog_flash: chip erase\n"); + memset(flash->content, 0xff, 1024 * 1024); + prog_flash_update(flash, 0, 1024 * 1024); +} + +static void prog_flash_write_half_word(void *data, uint32 adr, uint32 val, + struct profile *profile, + uint32 req_adr) { + struct prog_flash *flash = data; + int adr15 = (adr & 0xffff) >> 1; + int val8 = val & 0xff; + + logmsg(LOG_FW_FLASH, 10, "prog_flash: write %x to %x\n", val, adr); + + switch (flash->state) { + case 0: + if (adr15 == 0x5555 && val8 == 0xaa) + flash->state = 1; + break; + + case 1: + if (adr15 == 0x2aaa && val8 == 0x55) + flash->state = 2; + else + flash->state = 0; + break; + + case 2: + if (adr15 == 0x5555) { + switch (val8) { + case 0xa0: + case 0x80: + case 0x90: + case 0x98: + flash->state = val & 0xff; + break; + default: + flash->state = 0; + break; + } + } else + flash->state = 0; + break; + + case 0x80: + /* erase mode */ + if (adr15 == 0x5555 && val8 == 0xaa) + flash->state = 0x81; + else + flash->state = 0; + break; + + case 0x81: + if (adr15 == 0x2aaa && val8 == 0x55) + flash->state = 0x82; + else + flash->state = 0; + break; + + case 0x82: + switch (val8) { + case 0x30: + prog_flash_sector_erase(flash, adr >> 12); + flash->state = 0; + break; + case 0x50: + prog_flash_block_erase(flash, adr >> 16); + flash->state = 0; + break; + case 0x10: + if (adr15 == 0x5555) + prog_flash_chip_erase(flash); + flash->state = 0; + break; + default: + flash->state = 0; + break; + } + break; + case 0x90: + /* software id mode */ + if (adr15 == 0x5555 && val8 == 0xf0) + flash->state = 0; + break; + + case 0x98: + /* TODO: CFI query */ + flash->state = 0; + break; + + case 0xa0: + adr = adr & 0xffffe; + flash->content[adr] = val & 0xff; + flash->content[adr + 1] = val >> 8; + prog_flash_update(flash, adr, 2); + flash->state = 0; + break; + + default: + flash->state = 0; + break; + } +} + +static uint32 read_803(struct hardware *hardware, uint32 adr) { + logmsg(LOG_MEMORY, 5, "irq: read from %x\n", adr); + + if ((adr & 0xfff) < 0x500) + return hardware->irq_reg[(adr & 0xfff) >> 2]; + else + return ~0; +} + +static void write_803(struct hardware *hardware, uint32 adr, uint32 val) { + logmsg(LOG_MEMORY, 5, "irq: write %x to %x\n", val, adr); + + if ((adr & 0xfff) < 0x500) + hardware->irq_reg[(adr & 0xfff) >> 2] = val; +} + +int check_irq(void *data) { + struct hardware *hardware = data; + int i; + + if (hardware->irq_request) { + for (i = 0; i < 32; i++) + if (hardware->irq_request & (1 << i)) { + hardware->irq_request &= ~(1 << i); + hardware->irq_reg[0x40] = i * 8; + return 1; + } + } + return 0; +} + +void set_irq_request(struct hardware *hardware, int i) { + if (hardware->irq_reg[0x100 + i] & 0x10000) + hardware->irq_request |= (1 << i); +} + +/* Timer implementation is quite lame, but that is enough. More + advanced event handling (removing, changing time) would be + required. */ + +static void timer_handle(struct pnx0101_timer *timer) { + if (timer->ctrl & 0x80) { + unsigned int delta = tick - timer->last_tick; + if (timer->counter < delta) { + timer->counter = timer->reload; + set_irq_request(timer->hardware, 5 + timer->index); + } else + timer->counter -= delta; + } + timer->last_tick = tick; +} + +static void timer_add_event(struct pnx0101_timer *timer) { + if (!timer->active && (timer->ctrl & 0x80)) { + timer->active = 1; + timer->event.tick = tick + timer->counter + 1; + add_event(&(timer->event)); + } +} + +static void timer_event(struct event *e) { + struct pnx0101_timer *timer = e->data; + timer_handle(timer); + if (timer->ctrl & 0x80) { + e->tick = tick + timer->counter + 1; + add_event(e); + } else + timer->active = 0; +} + +static uint32 timer_read(struct hardware *hardware, uint32 addr) { + struct pnx0101_timer *timer = &(hardware->timer[(addr & 0x400) ? 1 : 0]); + timer_handle(timer); + switch (addr & 0xf) { + case 8: + logmsg(LOG_MEMORY, 10, "timer(%d): read from ctrl\n", timer->index); + return timer->ctrl; + default: + logmsg(LOG_MEMORY, 5, "timer(%d): read from %x\n", timer->index, addr); + } + return ~0; +} + +static void timer_write(struct hardware *hardware, + uint32 addr, uint32 val) { + struct pnx0101_timer *timer = &(hardware->timer[(addr & 0x400) ? 1 : 0]); + timer_handle(timer); + switch (addr & 0xf) { + case 0: + logmsg(LOG_MEMORY, 10, "timer(%d): write %x to reload\n", + timer->index, val); + timer->reload = timer->counter = val * 2; + timer_add_event(timer); + break; + case 8: + logmsg(LOG_MEMORY, 10, "timer(%d): write %x to ctrl\n", + timer->index, val); + timer->ctrl = val; + timer_add_event(timer); + break; + default: + logmsg(LOG_MEMORY, 5, "timer(%d): write %x to %x (pc=%8x)\n", + timer->index, val, addr, cpu->reg[15] - 4); + } +} + +static uint32 adc_read(struct hardware *hardware, uint32 adr) { + switch (adr) { + case 0: /* most of buttons */ + if (ui_get_key(2)) return 0x280; + if (ui_get_key(3)) return 0x300; + if (ui_get_key(4)) return 0x100; + if (ui_get_key(5)) return 0x20; + if (ui_get_key(6)) return 0x60; + if (ui_get_key(7)) return 0x1a0; + if (ui_get_key(8)) return 0x200; + return 0x3ff; + case 4: /* battery */ + return 450; + case 8: + if (ui_get_key(1)) return 0; + return 0x3ff; + default: + logmsg(LOG_ADC, 5, "adc: read from %x\n", adr); + } + return ~0; +} + +static void adc_write(struct hardware *hardware, uint32 adr, uint32 val) { + logmsg(LOG_ADC, 5, "adc: write %x to %x\n", val, adr); +} + +static uint32 audio_read(struct audio *audio, uint32 adr) { + switch (adr) { + case 0x384: + logmsg(LOG_MEMORY, 5, "audio: siocr read\n"); + return audio->siocr; + case 0x398: + logmsg(LOG_MEMORY, 5, "audio: dacctrl read\n"); + return audio->dacctrl; + case 0x3a0: + logmsg(LOG_MEMORY, 5, "audio: dacset read\n"); + return audio->dacset; + default: + logmsg(LOG_MEMORY, 5, "audio: read from %x\n", adr); + } + return ~0; +} + +static void audio_output(struct audio *audio, int channel, uint32 val) { + if (audio->out_file[channel]) { + fputc((val >> 8) & 0xff, audio->out_file[channel]); + fputc((val >> 16) & 0xff, audio->out_file[channel]); + } +} + +static void audio_write(struct audio *audio, + uint32 addr, uint32 val) { + switch (addr) { + case 0x280: + audio_output(audio, AUDIO_LEFT, val << 8); + break; + case 0x284: + audio_output(audio, AUDIO_RIGHT, val << 8); + break; + case 0x288: + audio_output(audio, AUDIO_LEFT, val); + break; + case 0x28c: + audio_output(audio, AUDIO_RIGHT, val); + break; + case 0x2a0: + audio_output(audio, AUDIO_LEFT, (val & 0xffff) << 8); + audio_output(audio, AUDIO_LEFT, (val >> 8) & 0xffff00); + break; + case 0x2c0: + audio_output(audio, AUDIO_RIGHT, (val & 0xffff) << 8); + audio_output(audio, AUDIO_RIGHT, (val >> 8) & 0xffff00); + break; + case 0x2e0: + audio_output(audio, AUDIO_LEFT, (val & 0xffff) << 8); + audio_output(audio, AUDIO_RIGHT, (val >> 8) & 0xffff00); + break; + case 0x384: + audio->siocr = val; + logmsg(LOG_MEMORY, 5, "audio: siocr set to %x (dai_oe=%d)\n", + val, bits(val, 7, 1)); + break; + case 0x398: + audio->dacctrl = val; + logmsg(LOG_MEMORY, 5, "audio: dacctrl set to %x " + "(rgain=%x, lgain=%x, deemph=%x, smute=%x, mode2fs=%x, " + "rolloff=%x, pslow=%x, ddac_pd=%x, ddac_inv=%x, sildet_t=%x, " + "ensildet=%x)\n", val, bits(val, 0, 8), bits(val, 8, 8), + bits(val, 16, 3), bits(val, 19, 1), bits(val, 20, 2), + bits(val, 22, 2), bits(val, 24, 1), bits(val, 25, 1), + bits(val, 26, 1), bits(val, 27, 2), bits(val, 29, 1)); + break; + case 0x3a0: + audio->dacset = val; + logmsg(LOG_MEMORY, 5, "audio: dacset set to %x " + "(rdynpon=%d, ldynpon=%d, lbi_dwa=%d, rbi_dwa=%d)\n", val, + bits(val, 8, 1), bits(val, 9, 1), bits(val, 10, 1), + bits(val, 11, 1)); + break; + default: + logmsg(LOG_MEMORY, 5, "audio: write %x to %x (pc=%8x)\n", + val, addr, cpu->reg[15] - 4); + } +} + +static uint32 clocks_read(struct clocks *clocks, uint32 adr) { + if (adr >= 0 && adr < 0x30) { + logmsg(LOG_CGU, 5, "cgu: read from base_scr %x\n", adr >> 2); + return clocks->base_scr[adr >> 2]; + } else if (adr >= 0x30 && adr < 0x60) { + logmsg(LOG_CGU, 5, "cgu: read from base_fs1 %x\n", (adr - 0x30) >> 2); + return clocks->base_fs1[(adr - 0x30) >> 2]; + } else if (adr >= 0x60 && adr < 0x90) { + logmsg(LOG_CGU, 5, "cgu: read from base_fs2 %x\n", (adr - 0x60) >> 2); + return clocks->base_fs2[(adr - 0x60) >> 2]; + } else if (adr >= 0x90 && adr < 0xc0) { + logmsg(LOG_CGU, 5, "cgu: read from base_ssr %x\n", (adr - 0x90) >> 2); + return clocks->base_ssr[(adr - 0x90) >> 2]; + } else if (adr >= 0xc0 && adr <= 0xc0 + 72 * 4) { + logmsg(LOG_CGU, 5, "cgu: read from clk_pcr %x\n", (adr - 0xc0) >> 2); + return clocks->clk_pcr[(adr - 0xc0) >> 2]; + } else if (adr >= 0x308 && adr <= 0x308 + 66 * 4) { + logmsg(LOG_CGU, 5, "cgu: read from clk_esr %x\n", (adr - 0x308) >> 2); + return clocks->clk_esr[(adr - 0x308) >> 2]; + } else if (adr >= 0x414 && adr <= 0x414 + 2 * 4) { + logmsg(LOG_CGU, 5, "cgu: read from base_bcr %x\n", (adr - 0x414) >> 2); + return clocks->base_bcr[(adr - 0x414) >> 2]; + } else if (adr >= 0x420 && adr <= 0x420 + 17 * 4) { + logmsg(LOG_CGU, 5, "cgu: read from base_fdc %x\n", (adr - 0x420) >> 2); + return clocks->base_fdc[(adr - 0x420) >> 2]; + } else if (adr >= 0xcac && adr <= 0xce0) { + logmsg(LOG_CGU, 5, "cgu: read from regcac %x\n", (adr - 0xcac)); + return ~0; + } else if (adr >= 0xce4 && adr <= 0xcfc) { + logmsg(LOG_CGU, 5, "cgu: read from regce4 %x\n", (adr - 0xce4)); + return ~0; + } else { + logmsg(LOG_CGU, 5, "cgu: read from %x\n", adr); + return -1; + } +} + +static void clocks_write(struct clocks *clocks, + uint32 adr, uint32 val) { + if (adr >= 0 && adr < 0x30) { + logmsg(LOG_CGU, 5, "cgu: write %x to base_scr %x\n", val, adr >> 2); + clocks->base_scr[adr >> 2] = val; + } else if (adr >= 0x30 && adr < 0x60) { + logmsg(LOG_CGU, 5, "cgu: write %x to base_fs1 %x\n", + val, (adr - 0x30) >> 2); + clocks->base_fs1[(adr - 0x30) >> 2] = val; + } else if (adr >= 0x60 && adr < 0x90) { + logmsg(LOG_CGU, 5, "cgu: write %x to base_fs2 %x\n", + val, (adr - 0x60) >> 2); + clocks->base_fs2[(adr - 0x60) >> 2] = val; + } else if (adr >= 0x90 && adr < 0xc0) { + logmsg(LOG_CGU, 5, "cgu: write %x to base_ssr %x\n", + val, (adr - 0x90) >> 2); + clocks->base_ssr[(adr - 0x90) >> 2] = val; + } else if (adr >= 0xc0 && adr <= 0xc0 + 72 * 4) { + logmsg(LOG_CGU, 5, "cgu: write %x to clk_pcr %x\n", + val, (adr - 0xc0) >> 2); + clocks->clk_pcr[(adr - 0xc0) >> 2] = val; + } else if (adr >= 0x308 && adr <= 0x308 + 66 * 4) { + logmsg(LOG_CGU, 5, "cgu: write %x to clk_esr %x\n", + val, (adr - 0x308) >> 2); + clocks->clk_esr[(adr - 0x308) >> 2] = val; + } else if (adr >= 0x414 && adr <= 0x414 + 2 * 4) { + logmsg(LOG_CGU, 5, "cgu: write %x to base_bcr %x\n", + val, (adr - 0x414) >> 2); + clocks->base_bcr[(adr - 0x414) >> 2] = val; + } else if (adr >= 0x420 && adr <= 0x420 + 17 * 4) { + int n = (adr - 0x420) >> 2; + logmsg(LOG_CGU, 5, "cgu: write %x (%x %x %x %x) to base_fdc %x\n", + val, + val >> ((n == 0x10) ? 13 : 11), + (val >> 3) & ((n == 0x10) ? 0x3ff : 0xff), + (val >> 2) & 1, + val & 1, + n); + clocks->base_fdc[(adr - 0x420) >> 2] = val; + } else if (adr >= 0xcac && adr <= 0xce0) { + logmsg(LOG_CGU, 5, "clocks: write %x to regcac %x\n", val, (adr - 0xcac)); + } else if (adr >= 0xce4 && adr <= 0xcfc) { + logmsg(LOG_CGU, 5, "clocks: write %x to regce4 %x\n", val, (adr - 0xce4)); + } else { + logmsg(LOG_CGU, 5, "clocks: write %x to %x\n", val, adr); + } +} + +static struct base_clock { + int first_div; + int n_div; + int first_clock; + int last_clock; +} base_clock[12] = + { + {0, 7, 0, 27}, + {7, 2, 28, 36}, + {9, 1, 37, 40}, + {10, 1, 41, 56}, + {0, 0, 57, 57}, + {0, 0, 58, 58}, + {0, 0, 59, 59}, + {0, 0, 60, 60}, + {11, 1, 61, 61}, + {12, 6, 62, 70}, + {0, 0, 71, 71}, + {0, 0, 72, 72} + }; + +static int clocks_clock_base_clock(int clock) { + int i; + for (i = 0; i < 12; i++) + if (base_clock[i].last_clock >= clock) + return i; + return -1; +} + +static void clocks_log_state(struct clocks *clocks) { + int i, esr; + esr = 0; + for (i = 0; i < 73; i++) { + int base_id; + base_id = clocks_clock_base_clock(i); + if (base_clock[base_id].n_div > 0) { + int div = base_clock[base_id].first_div + (clocks->clk_esr[esr] >> 1); + int divcfg = clocks->base_fdc[div]; + int madd, msub; + if (div != 16) { + madd = (divcfg >> 3) & 0xff; + msub = 256 - ((divcfg >> 11) & 0xff); + } else { + madd = (divcfg >> 3) & 0x3ff; + msub = 1024 - ((divcfg >> 13) & 0x3ff); + } + if (clocks->clk_esr[esr] & 1) + logmsg(LOG_CGU, 5, "cgu: clock %2d: divider %2d " + "(run:%d strtch:%d n:%d m:%d), input %d\n", + i, div, divcfg & 1, (divcfg >> 2) & 1, msub, madd + msub, + (clocks->base_scr[base_id] & 1) ? + clocks->base_fs1[base_id] : clocks->base_fs2[base_id]); + else + logmsg(LOG_CGU, 5, "cgu: clock %2d: no divider, input %d\n", + i, (clocks->base_scr[base_id] & 1) ? + clocks->base_fs1[base_id] : clocks->base_fs2[base_id]); + esr++; + } else + logmsg(LOG_CGU, 5, "cgu: clock %2d: input %d\n", + i, (clocks->base_scr[base_id] & 1) ? + clocks->base_fs1[base_id] : clocks->base_fs2[base_id]); + } +} + +static uint32 i2c_read(struct hardware *hardware, uint32 adr) { + switch (adr & 0xff) { + case 4: + logmsg(LOG_I2C, 5, "i2c: status read\n", adr); + return 0; + default: + logmsg(LOG_I2C, 5, "i2c: read from %x\n", adr); + } + return ~0; +} + +static void i2c_write(struct hardware *hardware, uint32 adr, uint32 val) { + logmsg(LOG_I2C, 5, "i2c: write %x to %x\n", val, adr); +} + +static uint8 *cache_read(struct mmu_block *b, uint32 adr, + struct profile *profile, uint32 req_adr) { + struct mmu_cache_line *l = &(b->cache->line[(adr >> 5) & 0x7f]); + uint32 tag_addr = adr & ~0x1f; + uint32 phys_adr; + uint8* data; + int i; + for (i = 0; i < 2; i++) + if (l->addr[i] == tag_addr) { + profile_count(profile, req_adr, PROFILE_CTR_CACHE_HITS, 1); + l->lru = i ^ 1; + return l->data[i] + (adr & 0x1f); + } + profile_count(profile, req_adr, PROFILE_CTR_CACHE_MISSES, 1); + data = l->data[l->lru]; + if (l->dirty[l->lru]) { + logmsg(LOG_MEMORY, 15, "cache flush %x\n", l->addr[l->lru]); + profile_count(profile, req_adr, PROFILE_CTR_CACHE_FLUSHES, 1); + phys_adr = b->cache->block[l->addr[l->lru] >> 21].phys_adr + + (l->addr[l->lru] & ((1 << 21) - 1) & ~0x1f); + for (i = 0; i < 32; i += 4) + memory_write_word(b->memory, phys_adr + i, get_word(data + i), + profile, req_adr); + l->dirty[l->lru] = 0; + } + + phys_adr = b->phys_adr + (adr & ((1 << 21) - 1) & ~0x1f); + l->addr[l->lru] = tag_addr; + logmsg(LOG_MEMORY, 15, "cache fetch %x\n", l->addr[l->lru]); + for (i = 0; i < 32; i += 4) + put_word(data + i, + memory_read_word(b->memory, phys_adr + i, profile, req_adr)); + l->lru ^= 1; + return data + (adr & 0x1f); +} + +static uint8 *cache_write(struct mmu_block *b, uint32 adr, + struct profile *profile, uint32 req_adr) { + struct mmu_cache_line *l = &(b->cache->line[(adr >> 5) & 0x7f]); + uint32 tag_addr = adr & ~0x1f; + int i; + + if (!(b->cache->settings & 6) || !b->cache_enabled) + return NULL; + + for (i = 0; i < 2; i++) + if (l->addr[i] == tag_addr) { + profile_count(profile, req_adr, PROFILE_CTR_CACHE_HITS, 1); + l->dirty[i] = 1; + l->lru = i ^ 1; + return l->data[i] + (adr & 0x1f); + } + profile_count(profile, req_adr, PROFILE_CTR_CACHE_MISSES, 1); + return NULL; +} + +static uint8 mmu_block_read(void *data, uint32 adr, + struct profile *profile, uint32 req_adr) { + struct mmu_block *b = data; + if ((b->cache->settings & 6) && b->cache_enabled) { + uint8 *p = cache_read(b, adr, profile, req_adr); + return *p; + } else + return memory_read(b->memory, b->phys_adr + (adr & ((1 << 21) - 1)), + profile, req_adr); +} + +static uint32 mmu_block_read_half_word(void *data, uint32 adr, + struct profile *profile, + uint32 req_adr) { + struct mmu_block *b = data; + if ((b->cache->settings & 6) && b->cache_enabled) { + uint8 *p = cache_read(b, adr, profile, req_adr); + return get_half_word(p); + } else + return memory_read_half_word(b->memory, + b->phys_adr + (adr & ((1 << 21) - 1)), + profile, req_adr); +} + +static uint32 mmu_block_read_word(void *data, uint32 adr, + struct profile *profile, + uint32 req_adr) { + struct mmu_block *b = data; + if ((b->cache->settings & 6) && b->cache_enabled) { + uint8 *p = cache_read(b, adr, profile, req_adr); + return get_word(p); + } else + return memory_read_word(b->memory, b->phys_adr + (adr & ((1 << 21) - 1)), + profile, req_adr); +} + +static void mmu_block_write(void *data, uint32 adr, uint8 val, + struct profile *profile, uint32 req_adr) { + struct mmu_block *b = data; + uint8 *p = cache_write(b, adr, profile, req_adr); + if (p) + *p = val; + else + memory_write(b->memory, b->phys_adr + (adr & ((1 << 21) - 1)), val, + profile, req_adr); +} + +static void mmu_block_write_half_word(void *data, uint32 adr, uint32 val, + struct profile *profile, uint32 req_adr) { + struct mmu_block *b = data; + uint8 *p = cache_write(b, adr, profile, req_adr); + if (p) + put_half_word(p, val); + else + memory_write_half_word(b->memory, + b->phys_adr + (adr & ((1 << 21) - 1)), val, profile, req_adr); +} + +static void mmu_block_write_word(void *data, uint32 adr, uint32 val, + struct profile *profile, uint32 req_adr) { + struct mmu_block *b = data; + uint8 *p = cache_write(b, adr, profile, req_adr); + if (p) + put_word(p, val); + else + memory_write_word(b->memory, b->phys_adr + (adr & ((1 << 21) - 1)), val, + profile, req_adr); +} + +static void mmu_set_mapping(struct hardware *hardware, + uint32 dest, uint32 src) { + hardware->mmu[dest >> 21].phys_block = src >> 21; + hardware->mmu[dest >> 21].phys_adr = src; +} + +static uint32 mmu_read(struct hardware *hardware, uint32 adr) { + if (adr >= 0x18 && adr < 0x58) + return hardware->mmu[(adr - 0x18) / 4].phys_block; + else if (adr == 4) + return hardware->cache.settings; + else { + logmsg(LOG_MEMORY, 5, "mmu: read from %x\n", adr); + return 0; + } +} + +static void mmu_write(struct hardware *hardware, uint32 adr, uint32 val) { + if (adr >= 0x18 && adr < 0x58) + mmu_set_mapping(hardware, (adr - 0x18) << 19, (val & 0x7ff) << 21); + else if (adr == 4) + hardware->cache.settings = val; + else if (adr == 8) { + int i; + for (i = 0; i < 16; i++) + hardware->mmu[i].cache_enabled = (val >> i) & 1; + } else + logmsg(LOG_MEMORY, 5, "mmu: write %x to register %x\n", val, adr); +} + +void initialize_mmu(struct hardware *hardware, struct memory *phys_memory, + struct memory *memory) { + int i; + hardware->memory = memory; + hardware->phys_memory = phys_memory; + memory_copy_configuration(memory, 0, 0xffffffff, phys_memory, 0); + for (i = 0; i < 128; i++) { + hardware->cache.line[i].lru = 0; + hardware->cache.line[i].addr[0] = 0xff000000; + hardware->cache.line[i].addr[1] = 0xff000000; + } + hardware->cache.settings = 0; + hardware->cache.block = hardware->mmu; + for (i = 0; i < 16; i++) { + hardware->mmu[i].phys_block = i; + hardware->mmu[i].phys_adr = i * 0x200000; + hardware->mmu[i].memory = phys_memory; + hardware->mmu[i].cache = &hardware->cache; + hardware->mmu[i].cache_enabled = 0; + set_area(memory, 0x200000 * i, 0x200000 * i + 0x1fffff, + mmu_block_read, mmu_block_write, + mmu_block_read_half_word, mmu_block_write_half_word, + mmu_block_read_word, mmu_block_write_word, + &(hardware->mmu[i])); + } + mmu_set_mapping(hardware, 0, 0x10400000); +} + +static void dma_add_event(struct dma_channel *ch) { + ch->event.tick = tick + 16 * 500; + add_event(&(ch->event)); +} + +static void dma_event(struct event *e) { + int size, i; + struct dma_channel *ch = e->data; + + for (i = 0; i < 16 && ch->enable; i++) { + int size = 2 - bits(ch->config, 10, 2); + uint32 s1 = (bits(ch->config, 5, 5) == 0) ? + ch->src + (ch->count << size) : ch->src; + uint32 d1 = (bits(ch->config, 0, 5) == 0) ? + ch->dest + (ch->count << size) : ch->dest; + + switch (size) { + case 0: + memory_write(ch->dma->memory, d1, + memory_read(ch->dma->memory, s1, NULL, 0), + NULL, 0); + break; + case 1: + memory_write_half_word(ch->dma->memory, d1, + memory_read_half_word(ch->dma->memory, s1, + NULL, 0), + NULL, 0); + break; + case 2: + logmsg(LOG_MEMORY, 5, "transferring %x -> %x\n", s1, d1); + memory_write_word(ch->dma->memory, d1, + memory_read_word(ch->dma->memory, s1, NULL, 0), + NULL, 0); + break; + } + + if (ch->count == ch->len / 2 && + !(ch->dma->inten & (1 << (2 * ch->n + 1)))) { + ch->dma->intstat |= 1 << (2 * ch->n + 1); + set_irq_request(ch->dma->hardware, 0x1c); + } + + if (ch->count == ch->len) { + if (!(ch->dma->inten & (1 << (2 * ch->n)))) { + ch->dma->intstat |= 1 << (2 * ch->n); + set_irq_request(ch->dma->hardware, 0x1c); + } + if (bits(ch->config, 18, 1)) + ch->count = 0; + else + ch->enable = 0; + if (bits(ch->config, 17, 1)) { + struct dma_channel *pair = + &(ch->dma->channel[bits(ch->config, 13, 3)]); + /* probably it's ok to put the same channel as paired, but + it's not very useful */ + if (!pair->enable && pair != ch) { + pair->enable = 1; + dma_add_event(pair); + } + } + } else + ch->count++; + } + + if (ch->enable) + dma_add_event(ch); +} + +static uint32 dma_read(struct dma_ctrl *dma, uint32 adr) { + switch (adr) { + case 0x400: + { + uint32 r = 0; + int i; + logmsg(LOG_MEMORY, 5, "dma: read from enable\n"); + for (i = 0; i < 8; i++) + if (dma->channel[i].enable) r |= 1 << i; + return r; + } + case 0x404: + logmsg(LOG_MEMORY, 5, "dma: read from intstat\n"); + return dma->intstat; + case 0x408: + logmsg(LOG_MEMORY, 5, "dma: read from inten\n"); + return dma->inten; + default: + if (adr >= 0 && adr <= 0x100) { + int ch = adr >> 5; + logmsg(LOG_MEMORY, 5, "dma(%d): read from %x\n", ch, adr); + switch (adr & 0x1f) { + case 0: + return dma->channel[ch].src; + case 4: + return dma->channel[ch].dest; + case 8: + return dma->channel[ch].len; + case 0xc: + return dma->channel[ch].config; + case 0x10: + return dma->channel[ch].enable; + case 0x1c: + return dma->channel[ch].count; + default: + return 0; + } + } else { + logmsg(LOG_MEMORY, 5, "dma: read from %x\n", adr); + return 0; + } + } +} + +static void dma_write_enable(struct dma_channel *ch, int val) { + if (!ch->enable && val) { + ch->enable = 1; + add_event(&(ch->event)); + } else if (ch->enable && !val) { + remove_event(&(ch->event)); + ch->enable = 0; + } +} + +static void dma_write(struct dma_ctrl *dma, uint32 adr, uint32 val) { + int i; + switch (adr) { + case 0x400: + logmsg(LOG_MEMORY, 5, "dma: write %x to enable\n", val); + for (i = 0; i < 8; i++) + dma_write_enable(&(dma->channel[i]), (val >> i) & 1); + break; + case 0x404: + logmsg(LOG_MEMORY, 5, "dma: write %x to intstat\n", val); + dma->intstat &= ~val; + break; + case 0x408: + logmsg(LOG_MEMORY, 5, "dma: write %x to inten\n", val); + dma->inten = val; + break; + case 0x410: + logmsg(LOG_MEMORY, 5, "dma: write to softint\n", val); + if (!(dma->inten & (1 << 30))) { + dma->intstat |= (1 << 30); + set_irq_request(dma->hardware, 0x1c); + } + break; + default: + if (adr >= 0x200 && adr < 0x280) + adr = ((adr & 0x70) << 1) | (adr & 0xf); + if (adr >= 0 && adr < 0x100) { + int chn = adr >> 5; + struct dma_channel *ch = &(dma->channel[chn]); + logmsg(LOG_MEMORY, 5, "dma(%d): write %x to %x\n", chn, val, adr); + switch (adr & 0x1f) { + case 0: + ch->src = val; + break; + case 4: + ch->dest = val; + break; + case 8: + ch->len = val & 0xfff; + break; + case 0xc: + ch->config = val; + break; + case 0x10: + dma_write_enable(ch, val & 1); + break; + case 0x1c: + ch->count = 0; + break; + } + } else + logmsg(LOG_MEMORY, 5, "dma: write %x to %x\n", val, adr); + } +} + +static void emu_write(struct hardware *hardware, uint32 adr, uint32 val) { + switch (adr & 0xff) { + case 0: + hardware->log_buf[hardware->log_ptr++] = val; + if (val == 0 || hardware->log_ptr >= sizeof(hardware->log_buf) - 1) { + hardware->log_buf[sizeof(hardware->log_buf) - 1] = 0; + logmsg(LOG_GENERAL, 5, "log: %s\n", hardware->log_buf); + fprintf(stderr, "%s\n", hardware->log_buf); + hardware->log_ptr = 0; + } + break; + } +} + +static uint8 hardware_flash_read(void *data, uint32 adr, + struct profile *profile, uint32 req_adr) { + struct hardware *hardware = data; + struct flash *flash; + int chip; + + chip = selected_flash(hardware); + if (chip == -1) { + logmsg(LOG_FLASH, 5, "flash: no chip selected during read from %x\n", adr); + return ~0; + } + + flash = hardware->flash[chip]; + if (!flash) + return ~0; + + return flash_read(flash, adr & 0xf); +} + +static void hardware_flash_write(void *data, uint32 adr, uint8 val, + struct profile *profile, uint32 req_adr) { + struct hardware *hardware = data; + struct flash *flash; + int chip; + + chip = selected_flash(hardware); + if (chip == -1) { + logmsg(LOG_FLASH, 5, "flash: no chip selected during write %x to %x\n", val, adr); + return; + } + + flash = hardware->flash[chip]; + if (!flash) + return; + + flash_write(flash, adr & 0xf, val); +} + +static int cgu_log_counter = 0; + +static uint32 hardware_read_word(void *data, uint32 adr, + struct profile *profile, uint32 req_adr) { + struct hardware *hardware = data; + + { + if (cgu_log_counter >= 10000) { + cgu_log_counter = 0; + clocks_log_state(&hardware->clocks); + } else + cgu_log_counter++; + } + + switch ((adr >> 8) & 0xfffc) { + case 0x30: + return gpio_read(data, adr); + case 0x40: + case 0x44: + case 0x48: + case 0x4c: + return clocks_read(&(hardware->clocks), adr & 0xfff); + case 0x80: + /* emc_read */ + return 0; + case 0x1040: + return lcd_read(hardware->lcd, adr); + case 0x1048: + case 0x104c: + return dma_read(&(hardware->dma_ctrl), adr & 0x7ff); + case 0x1050: + return mmu_read(hardware, adr & 0xff); + case 0x3000: + case 0x3004: + return read_803(data, adr); + case 0x24: + return adc_read(hardware, adr & 0xff); + case 0x200: + timer_read(hardware, adr & 0x7ff); + break; + case 0x204: + timer_read(hardware, adr & 0x7ff); + break; + case 0x208: + return i2c_read(hardware, adr & 0xff); + case 0x2000: + return audio_read(&(hardware->audio), adr & 0xfff); + default: + logmsg(LOG_MEMORY, 10, "read from %8x\n", adr); + return 0xffffffff; + } +} + +static uint32 hardware_read_half_word(void *data, uint32 adr, + struct profile *profile, + uint32 req_adr) { + struct hardware *hardware = data; + + switch ((adr >> 8) & 0xfffc) { + case 0x2000: + return audio_read(&(hardware->audio), adr & 0xfff); + default: + logmsg(LOG_MEMORY, 10, "read half word from %8x\n", adr); + return 0xffff; + } +} + +static void hardware_write_word(void *data, uint32 adr, uint32 val, + struct profile *profile, uint32 req_adr) { + struct hardware *hardware = data; + + switch ((adr >> 8) & 0xfffc) { + case 0x30: + gpio_write(data, adr, val); + break; + case 0x40: + case 0x44: + case 0x48: + case 0x4c: + clocks_write(&(hardware->clocks), adr & 0xfff, val); + break; + case 0x1040: + lcd_write(hardware->lcd, adr, val); + break; + case 0x1048: + case 0x104c: + dma_write(&(hardware->dma_ctrl), adr & 0x7ff, val); + break; + case 0x1050: + mmu_write(hardware, adr & 0xff, val); + break; + case 0x3000: + case 0x3004: + write_803(data, adr, val); + break; + case 0x24: + adc_write(hardware, adr & 0xff, val); + break; + case 0x208: + i2c_write(hardware, adr & 0xff, val); + break; + case 0x200: + timer_write(hardware, adr & 0x7ff, val); + break; + case 0x204: + timer_write(hardware, adr & 0x7ff, val); + break; + case 0x2000: + audio_write(&(hardware->audio), adr & 0xfff, val); + break; + case 0x3f00: + emu_write(hardware, adr & 0xff, val); + break; + default: + logmsg(LOG_MEMORY, 10, "write %8x to %8x (pc=%8x)\n", val, adr, cpu->reg[15] - 4); + } +} + +static void hardware_write_half_word(void *data, uint32 adr, uint32 val, + struct profile *profile, uint32 req_adr) { + struct hardware *hardware = data; + + switch ((adr >> 8) & 0xfffc) { + case 0x2000: + audio_write(&(hardware->audio), adr & 0xfff, val); + break; + default: + logmsg(LOG_MEMORY, 10, "write half word %8x to %8x (pc=%8x)\n", + val, adr, cpu->reg[15] - 4); + } +} + +void install_hardware(struct hardware *hardware, + struct memory *memory) { + set_area(memory, 0x80000000, 0x803fffff, + read_void, write_void, + hardware_read_half_word, hardware_write_half_word, + hardware_read_word, hardware_write_word, hardware); + set_area(memory, 0x20000000, 0x200fffff, + prog_flash_read_byte, write_void, + prog_flash_read_half_word, prog_flash_write_half_word, + prog_flash_read_word, write_word_void, + hardware->prog_flash); + set_area(memory, 0x28000000, 0x2800ffff, + hardware_flash_read, hardware_flash_write, + read_half_word_void, write_half_word_void, + read_word_void, write_word_void, hardware); + /* + set_area(memory, 0x24100000, 0x2410ffff, + usb_read, usb_write, + usb_read_half_word, usb_write_half_word, + usb_read_word, usb_write_word, hardware->usb); + */ +} + +struct prog_flash *create_prog_flash(char *fname) { + struct prog_flash *flash; + + flash = xmalloc(sizeof(struct prog_flash)); + if (!flash) + return NULL; + + flash->state = 0; + + flash->content = xmalloc(1024 * 1024); + if (!flash->content) { + free(flash); + return NULL; + } + memset(flash->content, 0xff, 1024 * 1024); + + flash->fp = fopen(fname, "r+"); + if (!flash->fp) { + error_sys("%s: ", fname); + free(flash->content); + free(flash); + return NULL; + } + + fread(flash->content, 1, 1024 * 1024, flash->fp); + return flash; +} + +void free_prog_flash(struct prog_flash *flash) { + if (flash) { + if (flash->fp) + fclose(flash->fp); + if (flash->content) + free(flash->content); + free(flash); + } +} + +void audio_reset(struct audio *audio) { + audio->dacctrl = audio->dacset = 0; + audio->siocr = 0x80; + + audio->out_file[0] = fopen("left.out", "wb"); + audio->out_file[1] = fopen("right.out", "wb"); +} + +void clocks_reset(struct clocks *clocks) { + int i; + for (i = 0; i < 12; i++) { + clocks->base_scr[i] = 0; + clocks->base_fs1[i] = 0; + clocks->base_fs2[i] = 0; + clocks->base_ssr[i] = 0; + } + for (i = 0; i < 73; i++) + clocks->clk_pcr[i] = 0; + for (i = 0; i < 67; i++) + clocks->clk_esr[i] = 0; + for (i = 0; i < 3; i++) + clocks->base_bcr[i] = 0; + for (i = 0; i < 18; i++) + clocks->base_fdc[i] = 0; +} + +void hardware_reset(struct hardware *hardware, struct memory *phys_memory) { + int i; + tick = 0; + for (i = 0; i < 8; i++) { + hardware->gpio_out[i] = ~0; + hardware->gpio_dir[i] = 0; + } + hardware->gpio_out[2] &= ~1; /* power off bit */ + + for (i = 0; i < 2; i++) { + hardware->timer[i].ctrl = 0; + hardware->timer[i].index = i; + hardware->timer[i].hardware = hardware; + hardware->timer[i].active = 0; + hardware->timer[i].event.f = timer_event; + hardware->timer[i].event.data = &(hardware->timer[i]); + } + + hardware->dma_ctrl.hardware = hardware; + hardware->dma_ctrl.memory = phys_memory; + hardware->dma_ctrl.inten = 0xffff; + hardware->dma_ctrl.intstat = 0; + for (i = 0; i < 8; i++) { + hardware->dma_ctrl.channel[i].event.f = dma_event; + hardware->dma_ctrl.channel[i].event.data = + &(hardware->dma_ctrl.channel[i]); + hardware->dma_ctrl.channel[i].n = i; + hardware->dma_ctrl.channel[i].dma = &(hardware->dma_ctrl); + } + + hardware->irq_request = 0; + + audio_reset(&(hardware->audio)); + clocks_reset(&(hardware->clocks)); + + hardware->log_ptr = 0; +} + +static int usb_get_connected(void *data, int port, int bit) { + return ((struct hardware *)data)->usb_connected; +} + +static int get_hold(void *data, int port, int bit) { + return !ui_get_key(9); +} + +static int get_port6b0(void *data, int port, int bit) { + return 0; +} + +static void set_backlight(void *data, int port, int bit, int v) { + logmsg(LOG_GPIO, 5, "backlight: set to %d\n", v); +} + +static void set_rtc_i2c(void *data, int port, int bit, int v) { + logmsg(LOG_GPIO, 5, "rtc: i2c %s set to %d\n", bit ? "scl" : "sda", v); +} + +static void set_power(void *data, int port, int bit, int v) { + if (v) { + logmsg(LOG_GPIO, 5, "gpio: power off"); + cpu->stop = CPU_STOP_QUIT; + } +} + +static void set_unknown_port(void *data, int port, int bit, int v) { + logmsg(LOG_GPIO, 5, "gpio: bit %d/%d set to %d\n", port, bit, v); +} + +void hardware_connect_flash(struct hardware *hardware, + int n, struct flash *flash) { + hardware->flash[n] = flash; +} + + +struct hardware *create_hardware(void) { + int i, j; + struct hardware *hardware = xmalloc(sizeof(struct hardware)); + if (!hardware) return NULL; + + hardware->prog_flash = create_prog_flash(prog_flash_file); + if (!hardware->prog_flash) + goto no_prog_flash; + + for (i = 0; i < 4; i++) + hardware->flash[i] = NULL; + + for (i = 0; i < 8; i++) + for (j = 0; j < 32; j++) { + hardware->gpio_handler[i][j].get = NULL; + hardware->gpio_handler[i][j].set = NULL; + } + + gpio_install_handler(hardware, 6, 3, + hardware, flash_get_busy, NULL); + + gpio_install_handler(hardware, 7, 0, + hardware, usb_get_connected, NULL); + + gpio_install_handler(hardware, 5, 2, + hardware, get_hold, NULL); + + gpio_install_handler(hardware, 6, 0, + hardware, get_port6b0, set_rtc_i2c); + gpio_install_handler(hardware, 6, 1, + hardware, NULL, set_rtc_i2c); + + gpio_install_handler(hardware, 3, 0, + hardware, NULL, set_backlight); + + gpio_install_handler(hardware, 2, 0, + hardware, NULL, set_power); + gpio_install_handler(hardware, 1, 9, + hardware, NULL, set_unknown_port); + gpio_install_handler(hardware, 1, 19, + hardware, NULL, set_unknown_port); + gpio_install_handler(hardware, 1, 11, + hardware, NULL, set_unknown_port); + gpio_install_handler(hardware, 3, 2, + hardware, NULL, set_unknown_port); + gpio_install_handler(hardware, 1, 8, + hardware, NULL, set_unknown_port); + gpio_install_handler(hardware, 3, 6, + hardware, NULL, set_unknown_port); + gpio_install_handler(hardware, 1, 16, + hardware, NULL, set_unknown_port); + gpio_install_handler(hardware, 5, 0, + hardware, NULL, set_unknown_port); + + hardware->lcd = create_lcd(); + if (!hardware->lcd) + goto no_lcd; + + + hardware->usb = create_usb(); + if (!hardware->usb) + goto no_usb; + hardware->usb_connected = 0; + + return hardware; + + no_usb: + free_lcd(hardware->lcd); + no_lcd: + fclose(hardware->flash[0]->fp); + no_fp: + free(hardware->flash[0]); + no_flash: + free_prog_flash(hardware->prog_flash); + no_prog_flash: + free(hardware); + err: + return NULL; + +} Index: utils/emuriver/ChangeLog =================================================================== Index: utils/emuriver/README =================================================================== --- utils/emuriver/README (revision 0) +++ utils/emuriver/README (revision 0) @@ -0,0 +1,146 @@ +README file for the iRiver iFP7XX emulator +------------------------------------------ + +This is an iRiver iFP7XX emulator created mainly to study its +hardware. It is quite early and incomplete version, but it has +already been useful in figuring out player hardware details. + +Command line options +-------------------- + + -l logfile Create the file named logfile and write log + --log logfile messages to it. What is written is hardcoded + in the log.c file. + + -g, --gdb Work as a GDB remote target. In this mode, + the emulator waits for a connection from GDB + on port 5555. + + -n, Disable ncurses user interface. + --disable-ui + + -f file Set the path to a data flash image (default flash.img) + --flash-image file + + -p file Set the path to an external program flash image + --prog-flash-image file (default prog_flash.bin). + + -i file Set the path to the first part of the firmware + --int-flash-image file (default ifp1.bin). + + --rockbox file Set the path to the file that, if present, + will be loaded at 0x24000000 and executed + (skipping the original firmware) + (default no file). + +-m model Selects one of the player models. Affects the +--model model flash disk size. Supported models are 790, 795, 799 + (default 790). + +-x Enable 8MB of RAM at address 0x30000000. +--extra-memory + +-P Enable profiling. After exiting, values of the + counters will be stored in a profile.out file. + +User interface +-------------- + +Player keys are mapped in the following way: + +short press long press key + 1 ! play + 2 @ a->b + 3 # record + space M select (joystick) + j J left + l L right + k K down + i I up + +To quit the emulator press the q key. Keys t, c and C are used by the +trainer (see below). + +Trainer +------- + +Trainer is not available in the SDL user interface, which currently +is the only one. + +Trainer is a feature allowing searching for a byte in memory having a +specific function, for example storing current volume. Its idea and +name come from utilities for patching computer games to have, for +example, an infinite number of lifes. + +To start a trainer press t. Then you can indicate whether the value +changed or not by pressing c in case it changed or C in case it did +not change. For example, to find a memory location storing the volume, +press t, change the volume, press c, change once more, press c and so +on. Remember that often the representation of the value on the screen +changes together with it, so try to change the screen without changing +the value and press C. + +The trainer searches only memory in the area 0x400000-0x40ffff. When +there is less than four possible locations, they are shown in the +bottom line. + +Firmware +-------- + +Firmware should be decrypted using ifp-decode in the 2files mode. +There is some tracing capability in the emulator, but in order for +it to work, addresses of functioms from the original firmware should +be compiled into the emulator. I do not distribute this names however. + +Flash images +------------ + +Empty flash images can be created with the included make_flash_img +utility: + +./make_flash_img flash.img data256 + +The program flash image can be created with the following command + +./make_flash_img prog_flash.img prog1024 ifp2.bin + +The ifp2.bin is the second file created during decoding of the firmware. + +The program flash is also used by the original firmware to store +settings. Sometimes there are such stored settings, that the player +starts in a mode not fully supported by the emulator and hangs. The +external program flash image (prog1024) should be recreated then. + +GDB target +---------- + +The emulator can work as a GDB remote target. To use it this way, +start it with the -g option and start GDB in another terminal. To +connect to the emulator type the following command in GDB: + +target remote localhost:5555 + +The emulator does not currently support setting regular breakpoints in +ROM. Hardware assisted breakpoints should be used instead. For +example: + +hb *0x805410 + +Obviously, the ARM targeted GDB should be used. You can find +instructions how to build such version at: + +http://www.rockbox.org/twiki/bin/view/Main/WebHome?topic=CrossCompiler + +The target name should be arm-elf. + +Putting a file to an emulated player +------------------------------------ + +There is a program called flashimgtool which may be used to manipulate +files on the flash disk image. Only ls, mkdir, get and put commands +are supported now. + +Comments +-------- + +Send any comments to tmal@mimuw.edu.pl. Index: utils/emuriver/config.h.in =================================================================== --- utils/emuriver/config.h.in (revision 0) +++ utils/emuriver/config.h.in (revision 0) @@ -0,0 +1,34 @@ +/* config.h.in. Generated from configure.in by autoheader. */ + +/* Define this if your system is big-endian */ +#undef CONFIG_BIGENDIAN + +/* Define this if you have curses.h */ +#undef HAVE_CURSES_H + +/* Define this if you have ncurses.h */ +#undef HAVE_NCURSES_H + +/* Define this if you have SDL */ +#undef HAVE_SDL + +/* 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 Index: utils/emuriver/gdb_scripts/putfile.gdb =================================================================== --- utils/emuriver/gdb_scripts/putfile.gdb (revision 0) +++ utils/emuriver/gdb_scripts/putfile.gdb (revision 0) @@ -0,0 +1,16 @@ +target remote localhost:5555 +thb *0x802438 if $r3 == 7 +c + +set *0x700 = 't' +set *0x702 = '.' +set *0x704 = 'o' +set *0x706 = 'g' +set *0x708 = 'g' +set *0x70a = 0 +call 0x802438(0x800, 0, 0x700, 7) +set $len = 500000 +set $buffer = 0x24080000 +restore /home/tomek/devel/iriver/gdb/jotun.ogg binary $buffer 0 $len +call 0x8025c8(0x800, $buffer, $len) +call 0x80279c(0x800) Index: utils/emuriver/config/mkinstalldirs =================================================================== --- utils/emuriver/config/mkinstalldirs (revision 0) +++ utils/emuriver/config/mkinstalldirs (revision 0) @@ -0,0 +1,40 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +# $Id: mkinstalldirs,v 1.13 1999/01/05 03:18:55 bje Exp $ + +errstatus=0 + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case "$pathcomp" in + -* ) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# mkinstalldirs ends here Egenskapsändringar för: utils/emuriver/config/mkinstalldirs ___________________________________________________________________ Added: svn:executable + * Index: utils/emuriver/config/missing =================================================================== --- utils/emuriver/config/missing (revision 0) +++ utils/emuriver/config/missing (revision 0) @@ -0,0 +1,198 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. +# Copyright (C) 1996, 1997, 2001, 2002 Free Software Foundation, Inc. +# Franc,ois 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.in; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +case "$1" in + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + yacc create \`y.tab.[ch]', if possible, from existing .[ch]" + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing - GNU libit 0.0" + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + + aclocal*) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acinclude.m4' or \`$configure_ac'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`$configure_ac'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acconfig.h' or \`$configure_ac'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' $configure_ac` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case "$f" in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`$configure_ac'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if [ ! -f y.tab.h ]; then + echo >y.tab.h + fi + if [ ! -f y.tab.c ]; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex|flex) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if [ ! -f lex.yy.c ]; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + makeinfo) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` + fi + touch $file + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and you do not seem to have it handy on your + system. You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequirements for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 Egenskapsändringar för: utils/emuriver/config/missing ___________________________________________________________________ Added: svn:executable + * Index: utils/emuriver/config/config.guess =================================================================== --- utils/emuriver/config/config.guess (revision 0) +++ utils/emuriver/config/config.guess (revision 0) @@ -0,0 +1,1465 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + +timestamp='2005-04-22' + +# 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 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You 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. +# +# 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 Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +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 (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +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 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # 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 -q "$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 ;' + +# 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 + +# 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 tupples: *-*-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 ;; + *) 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 __ELF__ >/dev/null + 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 0 ;; + amd64:OpenBSD:*:*) + echo x86_64-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + cats:OpenBSD:*:*) + echo arm-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + luna88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + macppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvmeppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mips64-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sun3:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit 0 ;; + macppc:MirBSD:*:*) + echo powerppc-unknown-mirbsd${UNAME_RELEASE} + exit 0 ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit 0 ;; + 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'` + exit 0 ;; + 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 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit 0;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit 0 ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + 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 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit 0 ;; + 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 0 ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + 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 0 ;; + 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 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + 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 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + # 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 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + 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 \ + && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && exit 0 + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit 0 ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + 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 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????: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 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + 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 0 ;; + *: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 + $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 + echo rs6000-ibm-aix3.2.5 + 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 0 ;; + *:AIX:*:[45]) + 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/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 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 + # avoid double evaluation of $set_cc_for_build + test -n "$CC_FOR_BUILD" || eval $set_cc_for_build + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit 0 ;; + 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 && $dummy && exit 0 + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + 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 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + 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 0 ;; + 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 0 ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit 0 ;; + x86:Interix*:[34]*) + echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' + exit 0 ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit 0 ;; + 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 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; + amd64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + *: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/[-(].*//'`-gnu + exit 0 ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit 0 ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit 0 ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit 0 ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit 0 ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #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-gnu" && exit 0 + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #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-gnu" && exit 0 + ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit 0 ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit 0 ;; + 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 ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit 0 ;; + 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-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit 0 ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit 0 ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit 0 ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit 0 ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit 0 ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #ifdef __INTEL_COMPILER + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 + test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 + ;; + 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 0 ;; + 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 0 ;; + 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 0 ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit 0 ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit 0 ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit 0 ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; + 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 0 ;; + i*86:*:5:[78]*) + 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 0 ;; + 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 0 ;; + 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 i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + 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 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit 0 ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit 0 ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 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 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *: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 0 ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit 0 ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit 0 ;; + 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 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + *86) UNAME_PROCESSOR=i686 ;; + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *: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 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; + *: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 0 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit 0 ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit 0 ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit 0 ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit 0 ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit 0 ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit 0 ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit 0 ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms && exit 0 ;; + I*) echo ia64-dec-vms && exit 0 ;; + V*) echo vax-dec-vms && exit 0 ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0 + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +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: Egenskapsändringar för: utils/emuriver/config/config.guess ___________________________________________________________________ Added: svn:executable + * Index: utils/emuriver/config/config.sub =================================================================== --- utils/emuriver/config/config.sub (revision 0) +++ utils/emuriver/config/config.sub (revision 0) @@ -0,0 +1,1569 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + +timestamp='2005-04-22' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# 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 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You 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. + +# 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. + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# 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. + +# 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 (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +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 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # 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 0;; + + * ) + 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-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \ + kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + 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) + os= + basic_machine=$1 + ;; + -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 + ;; + -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/'` + ;; + -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*) + 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 \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | msp430 \ + | ns16k | ns32k \ + | openrisc | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b \ + | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + + # 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-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | msp430-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + # 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 + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + 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 + ;; + cr16c) + basic_machine=cr16c-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 + ;; + 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'm not sure what "Sysv32" means. Should this be sysv3.2? + 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 + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + 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 + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + 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 + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + or32 | or32-*) + basic_machine=or32-unknown + os=-coff + ;; + 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 + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + 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) basic_machine=powerpc-unknown + ;; + ppc-*) 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-*) 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 + ;; + 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 + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + 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 + ;; + 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 + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + 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 + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-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 + ;; + sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b) + 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. + -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* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \ + | -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* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -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*) + # 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* \ + | -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 + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -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 + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + 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 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + 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 + ;; + *-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 + ;; + -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 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: Egenskapsändringar för: utils/emuriver/config/config.sub ___________________________________________________________________ Added: svn:executable + * Index: utils/emuriver/config/install-sh =================================================================== --- utils/emuriver/config/install-sh (revision 0) +++ utils/emuriver/config/install-sh (revision 0) @@ -0,0 +1,269 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# +# 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. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + chmodcmd="" + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# 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 $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 Egenskapsändringar för: utils/emuriver/config/install-sh ___________________________________________________________________ Added: svn:executable + * Index: utils/emuriver/TODO =================================================================== --- utils/emuriver/TODO (revision 0) +++ utils/emuriver/TODO (revision 0) @@ -0,0 +1,5 @@ +- .gdbinit with some useful functions +- controlling the keys and taking screenshots from GDB +- I2C +- how to handle detach? restart and wait for another client? +- audio Index: utils/emuriver/INSTALL =================================================================== --- utils/emuriver/INSTALL (revision 0) +++ utils/emuriver/INSTALL (revision 0) @@ -0,0 +1,182 @@ +Basic Installation +================== + + These are generic installation instructions. + + 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, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + 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 at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.in' is used to create `configure' by a program +called `autoconf'. You only need `configure.in' 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. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. 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. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. 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. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +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 must use a version of `make' that +supports the `VPATH' variable, such as 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 `..'. + + If you have to use a `make' that does not supports the `VPATH' +variable, you have 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. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=PATH' 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. + + 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'. + +Optional Features +================= + + 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. + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +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 host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +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. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--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. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. Index: utils/emuriver/COPYING =================================================================== --- utils/emuriver/COPYING (revision 0) +++ utils/emuriver/COPYING (revision 0) @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 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. Index: utils/emuriver/Makefile.am =================================================================== --- utils/emuriver/Makefile.am (revision 0) +++ utils/emuriver/Makefile.am (revision 0) @@ -0,0 +1,3 @@ +SUBDIRS = src + +EXTRA_DIST = gdb_scripts config Index: utils/emuriver/NEWS =================================================================== Index: utils/emuriver/aclocal.m4 =================================================================== --- utils/emuriver/aclocal.m4 (revision 0) +++ utils/emuriver/aclocal.m4 (revision 0) @@ -0,0 +1,1152 @@ +dnl aclocal.m4 generated automatically by aclocal 1.4-p6 + +dnl Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without +dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A +dnl PARTICULAR PURPOSE. + +# lib-prefix.m4 serial 4 (gettext-0.14.2) +dnl Copyright (C) 2001-2005 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and +dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't +dnl require excessive bracketing. +ifdef([AC_HELP_STRING], +[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])], +[AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])]) + +dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed +dnl to access previously installed libraries. The basic assumption is that +dnl a user will want packages to use other packages he previously installed +dnl with the same --prefix option. +dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate +dnl libraries, but is otherwise very convenient. +AC_DEFUN([AC_LIB_PREFIX], +[ + AC_BEFORE([$0], [AC_LIB_LINKFLAGS]) + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + dnl By default, look in $includedir and $libdir. + use_additional=yes + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + AC_LIB_ARG_WITH([lib-prefix], +[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib + --without-lib-prefix don't search for libraries in includedir and libdir], +[ + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + else + additional_includedir="$withval/include" + additional_libdir="$withval/lib" + fi + fi +]) + if test $use_additional = yes; then + dnl Potentially add $additional_includedir to $CPPFLAGS. + dnl But don't add it + dnl 1. if it's the standard /usr/include, + dnl 2. if it's already present in $CPPFLAGS, + dnl 3. if it's /usr/local/include and we are using GCC on Linux, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + for x in $CPPFLAGS; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + dnl Really add $additional_includedir to $CPPFLAGS. + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir" + fi + fi + fi + fi + dnl Potentially add $additional_libdir to $LDFLAGS. + dnl But don't add it + dnl 1. if it's the standard /usr/lib, + dnl 2. if it's already present in $LDFLAGS, + dnl 3. if it's /usr/local/lib and we are using GCC on Linux, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_libdir" != "X/usr/lib"; then + haveit= + for x in $LDFLAGS; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test "X$additional_libdir" = "X/usr/local/lib"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LDFLAGS. + LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir" + fi + fi + fi + fi + fi +]) + +dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix, +dnl acl_final_exec_prefix, containing the values to which $prefix and +dnl $exec_prefix will expand at the end of the configure script. +AC_DEFUN([AC_LIB_PREPARE_PREFIX], +[ + dnl Unfortunately, prefix and exec_prefix get only finally determined + dnl at the end of configure. + if test "X$prefix" = "XNONE"; then + acl_final_prefix="$ac_default_prefix" + else + acl_final_prefix="$prefix" + fi + if test "X$exec_prefix" = "XNONE"; then + acl_final_exec_prefix='${prefix}' + else + acl_final_exec_prefix="$exec_prefix" + fi + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" + prefix="$acl_save_prefix" +]) + +dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the +dnl variables prefix and exec_prefix bound to the values they will have +dnl at the end of the configure script. +AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX], +[ + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + $1 + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" +]) + +# lib-link.m4 serial 6 (gettext-0.14.3) +dnl Copyright (C) 2001-2005 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +AC_PREREQ(2.50) + +dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and +dnl the libraries corresponding to explicit and implicit dependencies. +dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and +dnl augments the CPPFLAGS variable. +AC_DEFUN([AC_LIB_LINKFLAGS], +[ + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + define([Name],[translit([$1],[./-], [___])]) + define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [ + AC_LIB_LINKFLAGS_BODY([$1], [$2]) + ac_cv_lib[]Name[]_libs="$LIB[]NAME" + ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME" + ac_cv_lib[]Name[]_cppflags="$INC[]NAME" + ]) + LIB[]NAME="$ac_cv_lib[]Name[]_libs" + LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs" + INC[]NAME="$ac_cv_lib[]Name[]_cppflags" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) + AC_SUBST([LIB]NAME) + AC_SUBST([LTLIB]NAME) + dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the + dnl results of this search when this library appears as a dependency. + HAVE_LIB[]NAME=yes + undefine([Name]) + undefine([NAME]) +]) + +dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode) +dnl searches for libname and the libraries corresponding to explicit and +dnl implicit dependencies, together with the specified include files and +dnl the ability to compile and link the specified testcode. If found, it +dnl sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME} and +dnl LTLIB${NAME} variables and augments the CPPFLAGS variable, and +dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs +dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty. +AC_DEFUN([AC_LIB_HAVE_LINKFLAGS], +[ + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + define([Name],[translit([$1],[./-], [___])]) + define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + + dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME + dnl accordingly. + AC_LIB_LINKFLAGS_BODY([$1], [$2]) + + dnl Add $INC[]NAME to CPPFLAGS before performing the following checks, + dnl because if the user has installed lib[]Name and not disabled its use + dnl via --without-lib[]Name-prefix, he wants to use it. + ac_save_CPPFLAGS="$CPPFLAGS" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) + + AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [ + ac_save_LIBS="$LIBS" + LIBS="$LIBS $LIB[]NAME" + AC_TRY_LINK([$3], [$4], [ac_cv_lib[]Name=yes], [ac_cv_lib[]Name=no]) + LIBS="$ac_save_LIBS" + ]) + if test "$ac_cv_lib[]Name" = yes; then + HAVE_LIB[]NAME=yes + AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the $1 library.]) + AC_MSG_CHECKING([how to link with lib[]$1]) + AC_MSG_RESULT([$LIB[]NAME]) + else + HAVE_LIB[]NAME=no + dnl If $LIB[]NAME didn't lead to a usable library, we don't need + dnl $INC[]NAME either. + CPPFLAGS="$ac_save_CPPFLAGS" + LIB[]NAME= + LTLIB[]NAME= + fi + AC_SUBST([HAVE_LIB]NAME) + AC_SUBST([LIB]NAME) + AC_SUBST([LTLIB]NAME) + undefine([Name]) + undefine([NAME]) +]) + +dnl Determine the platform dependent parameters needed to use rpath: +dnl libext, shlibext, hardcode_libdir_flag_spec, hardcode_libdir_separator, +dnl hardcode_direct, hardcode_minus_L. +AC_DEFUN([AC_LIB_RPATH], +[ + dnl Tell automake >= 1.10 to complain if config.rpath is missing. + m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([config.rpath])]) + AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS + AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld + AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host + AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir + AC_CACHE_CHECK([for shared library run path origin], acl_cv_rpath, [ + CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ + ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh + . ./conftest.sh + rm -f ./conftest.sh + acl_cv_rpath=done + ]) + wl="$acl_cv_wl" + libext="$acl_cv_libext" + shlibext="$acl_cv_shlibext" + hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" + hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" + hardcode_direct="$acl_cv_hardcode_direct" + hardcode_minus_L="$acl_cv_hardcode_minus_L" + dnl Determine whether the user wants rpath handling at all. + AC_ARG_ENABLE(rpath, + [ --disable-rpath do not hardcode runtime library paths], + :, enable_rpath=yes) +]) + +dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and +dnl the libraries corresponding to explicit and implicit dependencies. +dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables. +AC_DEFUN([AC_LIB_LINKFLAGS_BODY], +[ + define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + dnl By default, look in $includedir and $libdir. + use_additional=yes + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + AC_LIB_ARG_WITH([lib$1-prefix], +[ --with-lib$1-prefix[=DIR] search for lib$1 in DIR/include and DIR/lib + --without-lib$1-prefix don't search for lib$1 in includedir and libdir], +[ + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + else + additional_includedir="$withval/include" + additional_libdir="$withval/lib" + fi + fi +]) + dnl Search the library and its dependencies in $additional_libdir and + dnl $LDFLAGS. Using breadth-first-seach. + LIB[]NAME= + LTLIB[]NAME= + INC[]NAME= + rpathdirs= + ltrpathdirs= + names_already_handled= + names_next_round='$1 $2' + while test -n "$names_next_round"; do + names_this_round="$names_next_round" + names_next_round= + for name in $names_this_round; do + already_handled= + for n in $names_already_handled; do + if test "$n" = "$name"; then + already_handled=yes + break + fi + done + if test -z "$already_handled"; then + names_already_handled="$names_already_handled $name" + dnl See if it was already located by an earlier AC_LIB_LINKFLAGS + dnl or AC_LIB_HAVE_LINKFLAGS call. + uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` + eval value=\"\$HAVE_LIB$uppername\" + if test -n "$value"; then + if test "$value" = yes; then + eval value=\"\$LIB$uppername\" + test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value" + eval value=\"\$LTLIB$uppername\" + test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value" + else + dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined + dnl that this library doesn't exist. So just drop it. + : + fi + else + dnl Search the library lib$name in $additional_libdir and $LDFLAGS + dnl and the already constructed $LIBNAME/$LTLIBNAME. + found_dir= + found_la= + found_so= + found_a= + if test $use_additional = yes; then + if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext"; then + found_dir="$additional_libdir" + found_so="$additional_libdir/lib$name.$shlibext" + if test -f "$additional_libdir/lib$name.la"; then + found_la="$additional_libdir/lib$name.la" + fi + else + if test -f "$additional_libdir/lib$name.$libext"; then + found_dir="$additional_libdir" + found_a="$additional_libdir/lib$name.$libext" + if test -f "$additional_libdir/lib$name.la"; then + found_la="$additional_libdir/lib$name.la" + fi + fi + fi + fi + if test "X$found_dir" = "X"; then + for x in $LDFLAGS $LTLIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + case "$x" in + -L*) + dir=`echo "X$x" | sed -e 's/^X-L//'` + if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext"; then + found_dir="$dir" + found_so="$dir/lib$name.$shlibext" + if test -f "$dir/lib$name.la"; then + found_la="$dir/lib$name.la" + fi + else + if test -f "$dir/lib$name.$libext"; then + found_dir="$dir" + found_a="$dir/lib$name.$libext" + if test -f "$dir/lib$name.la"; then + found_la="$dir/lib$name.la" + fi + fi + fi + ;; + esac + if test "X$found_dir" != "X"; then + break + fi + done + fi + if test "X$found_dir" != "X"; then + dnl Found the library. + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name" + if test "X$found_so" != "X"; then + dnl Linking with a shared library. We attempt to hardcode its + dnl directory into the executable's runpath, unless it's the + dnl standard /usr/lib. + if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then + dnl No hardcoding is needed. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + dnl Use an explicit option to hardcode DIR into the resulting + dnl binary. + dnl Potentially add DIR to ltrpathdirs. + dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $found_dir" + fi + dnl The hardcoding into $LIBNAME is system dependent. + if test "$hardcode_direct" = yes; then + dnl Using DIR/libNAME.so during linking hardcodes DIR into the + dnl resulting binary. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then + dnl Use an explicit option to hardcode DIR into the resulting + dnl binary. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + dnl Potentially add DIR to rpathdirs. + dnl The rpathdirs will be appended to $LIBNAME at the end. + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $found_dir" + fi + else + dnl Rely on "-L$found_dir". + dnl But don't add it if it's already contained in the LDFLAGS + dnl or the already constructed $LIBNAME + haveit= + for x in $LDFLAGS $LIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir" + fi + if test "$hardcode_minus_L" != no; then + dnl FIXME: Not sure whether we should use + dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" + dnl here. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + dnl We cannot use $hardcode_runpath_var and LD_RUN_PATH + dnl here, because this doesn't fit in flags passed to the + dnl compiler. So give up. No hardcoding. This affects only + dnl very old systems. + dnl FIXME: Not sure whether we should use + dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" + dnl here. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" + fi + fi + fi + fi + else + if test "X$found_a" != "X"; then + dnl Linking with a static library. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a" + else + dnl We shouldn't come here, but anyway it's good to have a + dnl fallback. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name" + fi + fi + dnl Assume the include files are nearby. + additional_includedir= + case "$found_dir" in + */lib | */lib/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'` + additional_includedir="$basedir/include" + ;; + esac + if test "X$additional_includedir" != "X"; then + dnl Potentially add $additional_includedir to $INCNAME. + dnl But don't add it + dnl 1. if it's the standard /usr/include, + dnl 2. if it's /usr/local/include and we are using GCC on Linux, + dnl 3. if it's already present in $CPPFLAGS or the already + dnl constructed $INCNAME, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + for x in $CPPFLAGS $INC[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + dnl Really add $additional_includedir to $INCNAME. + INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir" + fi + fi + fi + fi + fi + dnl Look for dependencies. + if test -n "$found_la"; then + dnl Read the .la file. It defines the variables + dnl dlname, library_names, old_library, dependency_libs, current, + dnl age, revision, installed, dlopen, dlpreopen, libdir. + save_libdir="$libdir" + case "$found_la" in + */* | *\\*) . "$found_la" ;; + *) . "./$found_la" ;; + esac + libdir="$save_libdir" + dnl We use only dependency_libs. + for dep in $dependency_libs; do + case "$dep" in + -L*) + additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME. + dnl But don't add it + dnl 1. if it's the standard /usr/lib, + dnl 2. if it's /usr/local/lib and we are using GCC on Linux, + dnl 3. if it's already present in $LDFLAGS or the already + dnl constructed $LIBNAME, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_libdir" != "X/usr/lib"; then + haveit= + if test "X$additional_libdir" = "X/usr/local/lib"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + haveit= + for x in $LDFLAGS $LIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LIBNAME. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir" + fi + fi + haveit= + for x in $LDFLAGS $LTLIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LTLIBNAME. + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir" + fi + fi + fi + fi + ;; + -R*) + dir=`echo "X$dep" | sed -e 's/^X-R//'` + if test "$enable_rpath" != no; then + dnl Potentially add DIR to rpathdirs. + dnl The rpathdirs will be appended to $LIBNAME at the end. + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $dir" + fi + dnl Potentially add DIR to ltrpathdirs. + dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $dir" + fi + fi + ;; + -l*) + dnl Handle this in the next round. + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` + ;; + *.la) + dnl Handle this in the next round. Throw away the .la's + dnl directory; it is already contained in a preceding -L + dnl option. + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` + ;; + *) + dnl Most likely an immediate library name. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep" + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep" + ;; + esac + done + fi + else + dnl Didn't find the library; assume it is in the system directories + dnl known to the linker and runtime loader. (All the system + dnl directories known to the linker should also be known to the + dnl runtime loader, otherwise the system is severely misconfigured.) + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name" + fi + fi + fi + done + done + if test "X$rpathdirs" != "X"; then + if test -n "$hardcode_libdir_separator"; then + dnl Weird platform: only the last -rpath option counts, the user must + dnl pass all path elements in one option. We can arrange that for a + dnl single library, but not when more than one $LIBNAMEs are used. + alldirs= + for found_dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir" + done + dnl Note: hardcode_libdir_flag_spec uses $libdir and $wl. + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" + else + dnl The -rpath options are cumulative. + for found_dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$found_dir" + eval flag=\"$hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" + done + fi + fi + if test "X$ltrpathdirs" != "X"; then + dnl When using libtool, the option that works for both libraries and + dnl executables is -R. The -R options are cumulative. + for found_dir in $ltrpathdirs; do + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir" + done + fi +]) + +dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR, +dnl unless already present in VAR. +dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes +dnl contains two or three consecutive elements that belong together. +AC_DEFUN([AC_LIB_APPENDTOVAR], +[ + for element in [$2]; do + haveit= + for x in $[$1]; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + [$1]="${[$1]}${[$1]:+ }$element" + fi + done +]) + +# lib-ld.m4 serial 3 (gettext-0.13) +dnl Copyright (C) 1996-2003 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl Subroutines of libtool.m4, +dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision +dnl with libtool.m4. + +dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no. +AC_DEFUN([AC_LIB_PROG_LD_GNU], +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], acl_cv_prog_gnu_ld, +[# I'd rather use --version here, but apparently some GNU ld's only accept -v. +case `$LD -v 2>&1 conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by GCC]) + 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. + [[\\/]* | [A-Za-z]:[\\/]*)] + [re_direlt='/[^/][^/]*/\.\./'] + # Canonicalize the path 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 "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(acl_cv_path_LD, +[if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + acl_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in + *GNU* | *'with BFD'*) + test "$with_gnu_ld" != no && break ;; + *) + test "$with_gnu_ld" != yes && break ;; + esac + fi + done + IFS="$ac_save_ifs" +else + acl_cv_path_LD="$LD" # Let the user override the test with a path. +fi]) +LD="$acl_cv_path_LD" +if test -n "$LD"; then + AC_MSG_RESULT($LD) +else + AC_MSG_RESULT(no) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +AC_LIB_PROG_LD_GNU +]) + +# Like AC_CONFIG_HEADER, but automatically create stamp file. + +AC_DEFUN([AM_CONFIG_HEADER], +[AC_PREREQ([2.12]) +AC_CONFIG_HEADER([$1]) +dnl When config.status generates a header, we must update the stamp-h file. +dnl This file resides in the same directory as the config header +dnl that is generated. We must strip everything past the first ":", +dnl and everything past the last "/". +AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl +ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>, +<>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>, +<>; do + case " <<$>>CONFIG_HEADERS " in + *" <<$>>am_file "*<<)>> + echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx + ;; + esac + am_indx=`expr "<<$>>am_indx" + 1` +done<<>>dnl>>) +changequote([,]))]) + +# Do all the work for Automake. 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. + +# serial 1 + +dnl Usage: +dnl AM_INIT_AUTOMAKE(package,version, [no-define]) + +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL]) +PACKAGE=[$1] +AC_SUBST(PACKAGE) +VERSION=[$2] +AC_SUBST(VERSION) +dnl test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +fi +ifelse([$3],, +AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) +AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])) +AC_REQUIRE([AM_SANITY_CHECK]) +AC_REQUIRE([AC_ARG_PROGRAM]) +dnl FIXME This is truly gross. +missing_dir=`cd $ac_aux_dir && pwd` +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}, $missing_dir) +AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}, $missing_dir) +AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir) +AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir) +AC_REQUIRE([AC_PROG_MAKE_SET])]) + +# Copyright 2002 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + +# 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. +AC_DEFUN([AM_AUTOMAKE_VERSION],[am__api_version="1.4"]) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION so it can be traced. +# This function is AC_REQUIREd by AC_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], + [AM_AUTOMAKE_VERSION([1.4-p6])]) + +# +# Check to make sure that the build environment is sane. +# + +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftestfile +# 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 ( + set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` + if test "[$]*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftestfile` + fi + if test "[$]*" != "X $srcdir/configure conftestfile" \ + && test "[$]*" != "X conftestfile $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 + + test "[$]2" = conftestfile + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +rm -f conftest* +AC_MSG_RESULT(yes)]) + +dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY) +dnl The program must properly implement --version. +AC_DEFUN([AM_MISSING_PROG], +[AC_MSG_CHECKING(for working $2) +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if ($2 --version) < /dev/null > /dev/null 2>&1; then + $1=$2 + AC_MSG_RESULT(found) +else + $1="$3/missing $2" + AC_MSG_RESULT(missing) +fi +AC_SUBST($1)]) + +# Configure paths for SDL +# Sam Lantinga 9/21/99 +# stolen from Manish Singh +# stolen back from Frank Belew +# stolen from Manish Singh +# Shamelessly stolen from Owen Taylor + +dnl AM_PATH_SDL([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) +dnl Test for SDL, and define SDL_CFLAGS and SDL_LIBS +dnl +AC_DEFUN([AM_PATH_SDL], +[dnl +dnl Get the cflags and libraries from the sdl-config script +dnl +AC_ARG_WITH(sdl-prefix,[ --with-sdl-prefix=PFX Prefix where SDL is installed (optional)], + sdl_prefix="$withval", sdl_prefix="") +AC_ARG_WITH(sdl-exec-prefix,[ --with-sdl-exec-prefix=PFX Exec prefix where SDL is installed (optional)], + sdl_exec_prefix="$withval", sdl_exec_prefix="") +AC_ARG_ENABLE(sdltest, [ --disable-sdltest Do not try to compile and run a test SDL program], + , enable_sdltest=yes) + + if test x$sdl_exec_prefix != x ; then + sdl_args="$sdl_args --exec-prefix=$sdl_exec_prefix" + if test x${SDL_CONFIG+set} != xset ; then + SDL_CONFIG=$sdl_exec_prefix/bin/sdl-config + fi + fi + if test x$sdl_prefix != x ; then + sdl_args="$sdl_args --prefix=$sdl_prefix" + if test x${SDL_CONFIG+set} != xset ; then + SDL_CONFIG=$sdl_prefix/bin/sdl-config + fi + fi + + AC_REQUIRE([AC_CANONICAL_TARGET]) + PATH="$prefix/bin:$prefix/usr/bin:$PATH" + AC_PATH_PROG(SDL_CONFIG, sdl-config, no, [$PATH]) + min_sdl_version=ifelse([$1], ,0.11.0,$1) + AC_MSG_CHECKING(for SDL - version >= $min_sdl_version) + no_sdl="" + if test "$SDL_CONFIG" = "no" ; then + no_sdl=yes + else + SDL_CFLAGS=`$SDL_CONFIG $sdlconf_args --cflags` + SDL_LIBS=`$SDL_CONFIG $sdlconf_args --libs` + + sdl_major_version=`$SDL_CONFIG $sdl_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + sdl_minor_version=`$SDL_CONFIG $sdl_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + sdl_micro_version=`$SDL_CONFIG $sdl_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + if test "x$enable_sdltest" = "xyes" ; then + ac_save_CFLAGS="$CFLAGS" + ac_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $SDL_CFLAGS" + LIBS="$LIBS $SDL_LIBS" +dnl +dnl Now check if the installed SDL is sufficiently new. (Also sanity +dnl checks the results of sdl-config to some extent +dnl + rm -f conf.sdltest + AC_TRY_RUN([ +#include +#include +#include +#include "SDL.h" + +char* +my_strdup (char *str) +{ + char *new_str; + + if (str) + { + new_str = (char *)malloc ((strlen (str) + 1) * sizeof(char)); + strcpy (new_str, str); + } + else + new_str = NULL; + + return new_str; +} + +int main (int argc, char *argv[]) +{ + int major, minor, micro; + char *tmp_version; + + /* This hangs on some systems (?) + system ("touch conf.sdltest"); + */ + { FILE *fp = fopen("conf.sdltest", "a"); if ( fp ) fclose(fp); } + + /* HP/UX 9 (%@#!) writes to sscanf strings */ + tmp_version = my_strdup("$min_sdl_version"); + if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { + printf("%s, bad version string\n", "$min_sdl_version"); + exit(1); + } + + if (($sdl_major_version > major) || + (($sdl_major_version == major) && ($sdl_minor_version > minor)) || + (($sdl_major_version == major) && ($sdl_minor_version == minor) && ($sdl_micro_version >= micro))) + { + return 0; + } + else + { + printf("\n*** 'sdl-config --version' returned %d.%d.%d, but the minimum version\n", $sdl_major_version, $sdl_minor_version, $sdl_micro_version); + printf("*** of SDL required is %d.%d.%d. If sdl-config is correct, then it is\n", major, minor, micro); + printf("*** best to upgrade to the required version.\n"); + printf("*** If sdl-config was wrong, set the environment variable SDL_CONFIG\n"); + printf("*** to point to the correct copy of sdl-config, and remove the file\n"); + printf("*** config.cache before re-running configure\n"); + return 1; + } +} + +],, no_sdl=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + if test "x$no_sdl" = x ; then + AC_MSG_RESULT(yes) + ifelse([$2], , :, [$2]) + else + AC_MSG_RESULT(no) + if test "$SDL_CONFIG" = "no" ; then + echo "*** The sdl-config script installed by SDL could not be found" + echo "*** If SDL was installed in PREFIX, make sure PREFIX/bin is in" + echo "*** your path, or set the SDL_CONFIG environment variable to the" + echo "*** full path to sdl-config." + else + if test -f conf.sdltest ; then + : + else + echo "*** Could not run SDL test program, checking why..." + CFLAGS="$CFLAGS $SDL_CFLAGS" + LIBS="$LIBS $SDL_LIBS" + AC_TRY_LINK([ +#include +#include "SDL.h" + +int main(int argc, char *argv[]) +{ return 0; } +#undef main +#define main K_and_R_C_main +], [ return 0; ], + [ echo "*** The test program compiled, but did not run. This usually means" + echo "*** that the run-time linker is not finding SDL or finding the wrong" + echo "*** version of SDL. If it is not finding SDL, you'll need to set your" + echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" + echo "*** to the installed location Also, make sure you have run ldconfig if that" + echo "*** is required on your system" + echo "***" + echo "*** If you have an old version installed, it is best to remove it, although" + echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"], + [ echo "*** The test program failed to compile or link. See the file config.log for the" + echo "*** exact error that occured. This usually means SDL was incorrectly installed" + echo "*** or that you have moved SDL since it was installed. In the latter case, you" + echo "*** may want to edit the sdl-config script: $SDL_CONFIG" ]) + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + SDL_CFLAGS="" + SDL_LIBS="" + ifelse([$3], , :, [$3]) + fi + AC_SUBST(SDL_CFLAGS) + AC_SUBST(SDL_LIBS) + rm -f conf.sdltest +]) + Index: utils/emuriver/stamp-h.in =================================================================== --- utils/emuriver/stamp-h.in (revision 0) +++ utils/emuriver/stamp-h.in (revision 0) @@ -0,0 +1 @@ +timestamp