From 191af92d477b601b42165cec42ee76cd85129359 Mon Sep 17 00:00:00 2001 From: Jens Ahrensfeld Date: Sat, 13 Mar 2010 14:13:53 +0000 Subject: [PATCH] Initial version Committed on the Free edition of March Hare Software CVSNT Server. Upgrade to CVS Suite for more features and support: http://march-hare.com/cvsnt/ git-svn-id: http://moon:8086/svn/vhdl/trunk@790 cc03376c-175c-47c8-b038-4cd826a8556b --- lib/CPUs/MIPS/bsp/examples/Bessel.c | 87 + lib/CPUs/MIPS/bsp/examples/Makefile | 333 +++ lib/CPUs/MIPS/bsp/examples/aes256.c | 359 +++ lib/CPUs/MIPS/bsp/examples/aes256.h | 42 + lib/CPUs/MIPS/bsp/examples/aes256_1.c | 76 + lib/CPUs/MIPS/bsp/examples/barcode.c | 358 +++ lib/CPUs/MIPS/bsp/examples/barcode.new.c | 322 +++ lib/CPUs/MIPS/bsp/examples/basicmath_small.c | 84 + lib/CPUs/MIPS/bsp/examples/bogomips.c | 71 + lib/CPUs/MIPS/bsp/examples/cfiflash.c | 415 +++ lib/CPUs/MIPS/bsp/examples/cfiflash.h | 58 + lib/CPUs/MIPS/bsp/examples/crc32.c | 54 + lib/CPUs/MIPS/bsp/examples/crc32.h | 13 + lib/CPUs/MIPS/bsp/examples/cubic.c | 64 + lib/CPUs/MIPS/bsp/examples/delay_mips.c | 15 + lib/CPUs/MIPS/bsp/examples/demo.c | 67 + lib/CPUs/MIPS/bsp/examples/dhry.h | 430 +++ lib/CPUs/MIPS/bsp/examples/dhry_1.c | 402 +++ lib/CPUs/MIPS/bsp/examples/dhry_2.c | 192 ++ lib/CPUs/MIPS/bsp/examples/dttl.c | 261 ++ lib/CPUs/MIPS/bsp/examples/gunzip.c | 198 ++ lib/CPUs/MIPS/bsp/examples/hashtest.c | 323 +++ lib/CPUs/MIPS/bsp/examples/hello.c | 19 + lib/CPUs/MIPS/bsp/examples/hpi.c | 949 +++++++ lib/CPUs/MIPS/bsp/examples/hpi.h | 384 +++ lib/CPUs/MIPS/bsp/examples/inflate.c | 504 ++++ lib/CPUs/MIPS/bsp/examples/inflate.h | 15 + lib/CPUs/MIPS/bsp/examples/isqrt.c | 89 + lib/CPUs/MIPS/bsp/examples/life.c | 251 ++ lib/CPUs/MIPS/bsp/examples/lua_init.c | 1 + lib/CPUs/MIPS/bsp/examples/lwl.c | 46 + lib/CPUs/MIPS/bsp/examples/mandelbrot.c | 54 + lib/CPUs/MIPS/bsp/examples/paranoia.c | 2302 +++++++++++++++++ lib/CPUs/MIPS/bsp/examples/phrasen.c | 298 +++ lib/CPUs/MIPS/bsp/examples/pi.h | 13 + lib/CPUs/MIPS/bsp/examples/queens.c | 856 ++++++ lib/CPUs/MIPS/bsp/examples/r3.c | 471 ++++ lib/CPUs/MIPS/bsp/examples/rad2deg.c | 39 + lib/CPUs/MIPS/bsp/examples/random.c | 86 + lib/CPUs/MIPS/bsp/examples/random.h | 6 + .../MIPS/bsp/examples/richards_benchmark.c | 408 +++ lib/CPUs/MIPS/bsp/examples/rmd160.c | 294 +++ lib/CPUs/MIPS/bsp/examples/rmd160.h | 154 ++ lib/CPUs/MIPS/bsp/examples/rmd160_test.c | 113 + lib/CPUs/MIPS/bsp/examples/round.h | 55 + lib/CPUs/MIPS/bsp/examples/serdump.c | 83 + lib/CPUs/MIPS/bsp/examples/snipmath.h | 75 + lib/CPUs/MIPS/bsp/examples/sniptype.h | 37 + lib/CPUs/MIPS/bsp/examples/stanford.c | 1117 ++++++++ lib/CPUs/MIPS/bsp/examples/test_ac97.c | 310 +++ lib/CPUs/MIPS/bsp/examples/test_dcache.c | 61 + lib/CPUs/MIPS/bsp/examples/test_endianess.c | 64 + lib/CPUs/MIPS/bsp/examples/test_exception.c | 282 ++ lib/CPUs/MIPS/bsp/examples/test_flash.c | 94 + lib/CPUs/MIPS/bsp/examples/test_hpi.c | 848 ++++++ lib/CPUs/MIPS/bsp/examples/test_irq.c | 335 +++ lib/CPUs/MIPS/bsp/examples/test_mipsdis.c | 651 +++++ lib/CPUs/MIPS/bsp/examples/test_timer.c | 40 + lib/CPUs/MIPS/bsp/examples/test_vga.c | 206 ++ lib/CPUs/MIPS/bsp/examples/testbench.c | 1229 +++++++++ lib/CPUs/MIPS/bsp/examples/testlibusb.c | 210 ++ lib/CPUs/MIPS/bsp/examples/ucb.c | 44 + lib/CPUs/MIPS/bsp/examples/whet.c | 265 ++ 63 files changed, 17582 insertions(+) create mode 100644 lib/CPUs/MIPS/bsp/examples/Bessel.c create mode 100644 lib/CPUs/MIPS/bsp/examples/Makefile create mode 100644 lib/CPUs/MIPS/bsp/examples/aes256.c create mode 100644 lib/CPUs/MIPS/bsp/examples/aes256.h create mode 100644 lib/CPUs/MIPS/bsp/examples/aes256_1.c create mode 100644 lib/CPUs/MIPS/bsp/examples/barcode.c create mode 100644 lib/CPUs/MIPS/bsp/examples/barcode.new.c create mode 100644 lib/CPUs/MIPS/bsp/examples/basicmath_small.c create mode 100644 lib/CPUs/MIPS/bsp/examples/bogomips.c create mode 100644 lib/CPUs/MIPS/bsp/examples/cfiflash.c create mode 100644 lib/CPUs/MIPS/bsp/examples/cfiflash.h create mode 100644 lib/CPUs/MIPS/bsp/examples/crc32.c create mode 100644 lib/CPUs/MIPS/bsp/examples/crc32.h create mode 100644 lib/CPUs/MIPS/bsp/examples/cubic.c create mode 100644 lib/CPUs/MIPS/bsp/examples/delay_mips.c create mode 100644 lib/CPUs/MIPS/bsp/examples/demo.c create mode 100644 lib/CPUs/MIPS/bsp/examples/dhry.h create mode 100644 lib/CPUs/MIPS/bsp/examples/dhry_1.c create mode 100644 lib/CPUs/MIPS/bsp/examples/dhry_2.c create mode 100644 lib/CPUs/MIPS/bsp/examples/dttl.c create mode 100644 lib/CPUs/MIPS/bsp/examples/gunzip.c create mode 100644 lib/CPUs/MIPS/bsp/examples/hashtest.c create mode 100644 lib/CPUs/MIPS/bsp/examples/hello.c create mode 100644 lib/CPUs/MIPS/bsp/examples/hpi.c create mode 100644 lib/CPUs/MIPS/bsp/examples/hpi.h create mode 100644 lib/CPUs/MIPS/bsp/examples/inflate.c create mode 100644 lib/CPUs/MIPS/bsp/examples/inflate.h create mode 100644 lib/CPUs/MIPS/bsp/examples/isqrt.c create mode 100644 lib/CPUs/MIPS/bsp/examples/life.c create mode 100644 lib/CPUs/MIPS/bsp/examples/lua_init.c create mode 100644 lib/CPUs/MIPS/bsp/examples/lwl.c create mode 100644 lib/CPUs/MIPS/bsp/examples/mandelbrot.c create mode 100644 lib/CPUs/MIPS/bsp/examples/paranoia.c create mode 100644 lib/CPUs/MIPS/bsp/examples/phrasen.c create mode 100644 lib/CPUs/MIPS/bsp/examples/pi.h create mode 100644 lib/CPUs/MIPS/bsp/examples/queens.c create mode 100644 lib/CPUs/MIPS/bsp/examples/r3.c create mode 100644 lib/CPUs/MIPS/bsp/examples/rad2deg.c create mode 100644 lib/CPUs/MIPS/bsp/examples/random.c create mode 100644 lib/CPUs/MIPS/bsp/examples/random.h create mode 100644 lib/CPUs/MIPS/bsp/examples/richards_benchmark.c create mode 100644 lib/CPUs/MIPS/bsp/examples/rmd160.c create mode 100644 lib/CPUs/MIPS/bsp/examples/rmd160.h create mode 100644 lib/CPUs/MIPS/bsp/examples/rmd160_test.c create mode 100644 lib/CPUs/MIPS/bsp/examples/round.h create mode 100644 lib/CPUs/MIPS/bsp/examples/serdump.c create mode 100644 lib/CPUs/MIPS/bsp/examples/snipmath.h create mode 100644 lib/CPUs/MIPS/bsp/examples/sniptype.h create mode 100644 lib/CPUs/MIPS/bsp/examples/stanford.c create mode 100644 lib/CPUs/MIPS/bsp/examples/test_ac97.c create mode 100644 lib/CPUs/MIPS/bsp/examples/test_dcache.c create mode 100644 lib/CPUs/MIPS/bsp/examples/test_endianess.c create mode 100644 lib/CPUs/MIPS/bsp/examples/test_exception.c create mode 100644 lib/CPUs/MIPS/bsp/examples/test_flash.c create mode 100644 lib/CPUs/MIPS/bsp/examples/test_hpi.c create mode 100644 lib/CPUs/MIPS/bsp/examples/test_irq.c create mode 100644 lib/CPUs/MIPS/bsp/examples/test_mipsdis.c create mode 100644 lib/CPUs/MIPS/bsp/examples/test_timer.c create mode 100644 lib/CPUs/MIPS/bsp/examples/test_vga.c create mode 100644 lib/CPUs/MIPS/bsp/examples/testbench.c create mode 100644 lib/CPUs/MIPS/bsp/examples/testlibusb.c create mode 100644 lib/CPUs/MIPS/bsp/examples/ucb.c create mode 100644 lib/CPUs/MIPS/bsp/examples/whet.c diff --git a/lib/CPUs/MIPS/bsp/examples/Bessel.c b/lib/CPUs/MIPS/bsp/examples/Bessel.c new file mode 100644 index 0000000..080fe17 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/Bessel.c @@ -0,0 +1,87 @@ +/************************************************************************/ +/* Ein Programm zur Berechnung der Bessel-Koeffizienten Jn +/* Dateiname : Bessel.cpp +/* Autoren : T. Burr, J. Ahrensfeld +/* Datum : 28.10.1999 +/* letzte Änderung : 28.01.2000 +/* Version : 1.0 +/************************************************************************/ + +#include "stdio.h" +#include "math.h" +#include "stdlib.h" + + +#define MAX_SUM 25 +#define VERSION "1.0" + +/************************************************************************/ +/* Funktionsdeklarationen */ +/************************************************************************/ +// Fakultätsberechnung +double fak (int N) +{ + int index; + double erg=1; + + for (index = 1; index <= N; index++) + erg = erg * index; + + return erg; +} + +// Bessel() +// Berechnung von Jn von mfm +double bessel(int n, double mfm) +{ + int m; + double Jn=0; + + for (m=0; m < MAX_SUM; m++) + { + Jn = Jn + (pow(-1.0,m)/(fak(m)*fak(m+n))*pow(mfm/2.0,(2*m+n))); + } + return Jn; +} + + +/************************************************************************/ +/* Das Hauptprogramm +/************************************************************************/ +void main() +{ + + int N, Nmax; + double erg; + float mfm; + + printf("\n\t Besselfunktion Version %s",VERSION); + printf("\n\t ~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); + printf("\n\tCopyright by J. Ahrensfeld & T. Burr\n\n"); + +// --------------------------------------------------------------------------------- + // Benutzereingaben + printf("\nBerechnungen fuer J = 0..."); + if(scanf("%d",&Nmax)==0) + exit (-1); + + printf("Bitte Modulationsindex eingeben : "); + if(scanf("%f",&mfm)==0) + exit(-1); + + printf("\n"); + +// --------------------------------------------------------------------------------- + // Berechnung + for (N=0; N <= Nmax; N++) + { + erg = bessel(N,(double)mfm); + printf("J(%d) = %10.8f\n",N,erg); + } + + printf("FERTIG.\n"); + + } + +/************************************************************************/ + diff --git a/lib/CPUs/MIPS/bsp/examples/Makefile b/lib/CPUs/MIPS/bsp/examples/Makefile new file mode 100644 index 0000000..71d95b0 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/Makefile @@ -0,0 +1,333 @@ +ENDIAN='big' + +ifeq ($(ENDIAN), 'big') + ENDIAN_FLAGS=-EB + CFLAGS=$(ENDIAN_FLAGS) -specs=specs/eb/specs -msoft-float -O2 -march=r3000 -I. -Ilibsys -Wl,-M +else + ENDIAN_FLAGS=-EL + CFLAGS=$(ENDIAN_FLAGS) -specs=specs/specs -msoft-float -O2 -march=r3000 -I. -Ilibsys -Wl,-M +endif + +LIBS=-lm -lsys + +AS=mipsel-elf-as +AR=mipsel-elf-ar +CC=mipsel-elf-gcc +LD=mipsel-elf-ld +OBJDUMP=mipsel-elf-objdump +OBJCOPY=mipsel-elf-objcopy +FLASHGEN=flashgen + +PROG = hello.elf testbench.elf test_irq.elf dhry.elf queens.elf stanford.elf paranoia.elf rmd160_test.elf Bessel.elf whet.elf phrasen.elf dttl.elf richards_benchmark.elf test_exception.elf life.elf r3.elf gunzip.elf basic_math.elf jman_patches.elf jman_patchmeshes.elf jman_polys.elf test_hpi.elf test_vga.elf + +all: $(PROG) + +libsys.a: + $(MAKE) -C libsys + +hello.elf: hello.c libsys.a + $(CC) $(CFLAGS) -o $@ -Os hello.c $(LIBS) >$@.map + $(OBJDUMP) -d $@ > $@.dis + $(OBJCOPY) $@ -O binary $@.bin + $(OBJCOPY) -O srec $@ $@.srec + $(FLASHGEN) $@.bin $(ENDIAN_FLAGS) + cat $@.srec | packhex > $@.pack + +testbench.elf: testbench.c libsys.a + $(CC) $(CFLAGS) -O3 -o $@ -DHZ=1000 -DNOSIGNAL -DBATCHMODE -DNOMAIN -Os -g testbench.c paranoia.c delay_mips.c bogomips.c $(LIBS) >$@.map + $(OBJDUMP) -d $@ > $@.dis + $(OBJCOPY) $@ -O binary $@.bin + $(OBJCOPY) -O srec $@ $@.srec + $(FLASHGEN) $@.bin $(ENDIAN_FLAGS) + cat $@.srec | packhex > $@.pack + +test_irq.elf: test_irq.c libsys.a + $(CC) $(CFLAGS) -o $@ test_irq.c $(LIBS) >$@.map + $(OBJDUMP) -d $@ > $@.dis + $(OBJCOPY) $@ -O binary $@.bin + $(OBJCOPY) -O srec $@ $@.srec + $(FLASHGEN) $@.bin $(ENDIAN_FLAGS) + cat $@.srec | packhex > $@.pack + +dhry.elf: dhry_1.c dhry_2.c dhry.h libsys.a + $(CC) $(CFLAGS) -o $@ -DHZ=1000 dhry_1.c dhry_2.c $(LIBS) >$@.map + $(OBJDUMP) -d $@ > $@.dis + $(OBJCOPY) $@ -O binary $@.bin + $(OBJCOPY) -O srec $@ $@.srec + $(FLASHGEN) $@.bin $(ENDIAN_FLAGS) + cat $@.srec | packhex > $@.pack + +queens.elf: queens.c libsys.a + $(CC) $(CFLAGS) -o $@ -DUNIX_Old -DHZ=1000 queens.c $(LIBS) >$@.map + $(OBJDUMP) -d $@ > $@.dis + $(OBJCOPY) $@ -O binary $@.bin + $(OBJCOPY) -O srec $@ $@.srec + $(FLASHGEN) $@.bin $(ENDIAN_FLAGS) + cat $@.srec | packhex > $@.pack + +stanford.elf: stanford.c libsys.a + $(CC) $(CFLAGS) -O3 -o $@ -DHZ=1000 stanford.c $(LIBS) >$@.map + $(OBJDUMP) -d $@ > $@.dis + $(OBJCOPY) $@ -O binary $@.bin + $(OBJCOPY) -O srec $@ $@.srec + $(FLASHGEN) $@.bin $(ENDIAN_FLAGS) + cat $@.srec | packhex > $@.pack + +paranoia.elf: paranoia.c libsys.a + $(CC) $(CFLAGS) -O3 -o $@ -DNOSIGNAL -DBATCHMODE paranoia.c $(LIBS) >$@.map + $(OBJDUMP) -d $@ > $@.dis + $(OBJCOPY) $@ -O binary $@.bin + $(OBJCOPY) -O srec $@ $@.srec + $(FLASHGEN) $@.bin $(ENDIAN_FLAGS) + cat $@.srec | packhex > $@.pack + +rmd160_test.elf: rmd160_test.c rmd160.c rmd160.h libsys.a + $(CC) $(CFLAGS) -O3 -o $@ rmd160_test.c rmd160.c $(LIBS) >$@.map + $(OBJDUMP) -d $@ > $@.dis + $(OBJCOPY) $@ -O binary $@.bin + $(OBJCOPY) -O srec $@ $@.srec + $(FLASHGEN) $@.bin $(ENDIAN_FLAGS) + cat $@.srec | packhex > $@.pack + +hashtest.elf: hashtest.c rmd160.c rmd160.h libsys.a + $(CC) $(CFLAGS) -O3 -o $@ hashtest.c rmd160.c $(LIBS) >$@.map + $(OBJDUMP) -d $@ > $@.dis + $(OBJCOPY) $@ -O binary $@.bin + $(OBJCOPY) -O srec $@ $@.srec + $(FLASHGEN) $@.bin $(ENDIAN_FLAGS) + cat $@.srec | packhex > $@.pack + +Bessel.elf: Bessel.c libsys.a + $(CC) $(CFLAGS) -o $@ Bessel.c $(LIBS) >$@.map + $(OBJDUMP) -d $@ > $@.dis + $(OBJCOPY) $@ -O binary $@.bin + $(OBJCOPY) -O srec $@ $@.srec + $(FLASHGEN) $@.bin $(ENDIAN_FLAGS) + cat $@.srec | packhex > $@.pack + +whet.elf: whet.c libsys.a + $(CC) $(CFLAGS) -o $@ whet.c $(LIBS) >$@.map + $(OBJDUMP) -d $@ > $@.dis + $(OBJCOPY) $@ -O binary $@.bin + $(OBJCOPY) -O srec $@ $@.srec + $(FLASHGEN) $@.bin $(ENDIAN_FLAGS) + cat $@.srec | packhex > $@.pack + +phrasen.elf: phrasen.c libsys.a + $(CC) $(CFLAGS) -o $@ phrasen.c $(LIBS) >$@.map + $(OBJDUMP) -d $@ > $@.dis + $(OBJCOPY) $@ -O binary $@.bin + $(OBJCOPY) -O srec $@ $@.srec + $(FLASHGEN) $@.bin $(ENDIAN_FLAGS) + cat $@.srec | packhex > $@.pack + +dttl.elf: dttl.c random.c libsys.a + $(CC) $(CFLAGS) -o $@ dttl.c random.c $(LIBS) >$@.map + $(OBJDUMP) -d $@ > $@.dis + $(OBJCOPY) $@ -O binary $@.bin + $(OBJCOPY) -O srec $@ $@.srec + $(FLASHGEN) $@.bin $(ENDIAN_FLAGS) + cat $@.srec | packhex > $@.pack + +richards_benchmark.elf: richards_benchmark.c libsys.a + $(CC) $(CFLAGS) -o $@ richards_benchmark.c $(LIBS) >$@.map + $(OBJDUMP) -d $@ > $@.dis + $(OBJCOPY) $@ -O binary $@.bin + $(OBJCOPY) -O srec $@ $@.srec + $(FLASHGEN) $@.bin $(ENDIAN_FLAGS) + cat $@.srec | packhex > $@.pack + +test_exception.elf: test_exception.c libsys.a + $(CC) $(CFLAGS) -o $@ -O1 test_exception.c $(LIBS) >$@.map + $(OBJDUMP) -d $@ > $@.dis + $(OBJCOPY) $@ -O binary $@.bin + $(OBJCOPY) -O srec $@ $@.srec + $(FLASHGEN) $@.bin $(ENDIAN_FLAGS) + cat $@.srec | packhex > $@.pack + +life.elf: life.c libsys.a + $(CC) $(CFLAGS) -o $@ -g life.c $(LIBS) >$@.map + $(OBJDUMP) -d $@ > $@.dis + $(OBJCOPY) $@ -O binary $@.bin + $(OBJCOPY) -O srec $@ $@.srec + $(FLASHGEN) $@.bin $(ENDIAN_FLAGS) + cat $@.srec | packhex > $@.pack + +r3.elf: r3.c libsys.a + $(CC) $(CFLAGS) -O3 -o $@ -DJMIPS_VGA -O2 r3.c $(LIBS) >$@.map + $(OBJDUMP) -d $@ > $@.dis + $(OBJCOPY) $@ -O binary $@.bin + $(OBJCOPY) -O srec $@ $@.srec + $(FLASHGEN) $@.bin $(ENDIAN_FLAGS) + cat $@.srec | packhex > $@.pack + +gunzip.elf: gunzip.c inflate.c crc32.c libsys.a + $(CC) $(CFLAGS) -o $@ -o $@ gunzip.c inflate.c crc32.c $(LIBS) >$@.map + $(OBJDUMP) -d $@ > $@.dis + $(OBJCOPY) $@ -O binary $@.bin + $(OBJCOPY) -O srec $@ $@.srec + $(FLASHGEN) $@.bin $(ENDIAN_FLAGS) + cat $@.srec | packhex > $@.pack + +basic_math.elf: basicmath_small.c rad2deg.c cubic.c isqrt.c libsys.a + $(CC) $(CFLAGS) -o $@ -o $@ basicmath_small.c rad2deg.c cubic.c isqrt.c $(LIBS) >$@.map + $(OBJDUMP) -d $@ > $@.dis + $(OBJCOPY) $@ -O binary $@.bin + $(OBJCOPY) -O srec $@ $@.srec + $(FLASHGEN) $@.bin $(ENDIAN_FLAGS) + cat $@.srec | packhex > $@.pack + +JMAN_SRC= \ + jman/bintree.c \ + jman/camset.c \ + jman/engine.c \ + jman/graph_state.c \ + jman/grid.c \ + jman/imageio.c \ + jman/linklist.c \ + jman/matrix.c \ + jman/object.c \ + jman/render.c \ + jman/ri.c \ + jman/ribgen.c \ + jman/stack.c \ + jman/vars.c + +jman_patches.elf: $(JMAN_SRC) jman/main_patches.c libsys.a + $(CC) $(CFLAGS) -I../ -o $@ -o $@ jman/main_patches.c $(JMAN_SRC) $(LIBS) >$@.map + $(OBJDUMP) -d $@ > $@.dis + $(OBJCOPY) $@ -O binary $@.bin + $(OBJCOPY) -O srec $@ $@.srec + $(FLASHGEN) $@.bin $(ENDIAN_FLAGS) + cat $@.srec | packhex > $@.pack + +jman_patchmeshes.elf: $(JMAN_SRC) jman/main_patchmeshes.c jman/patches2.c libsys.a + $(CC) $(CFLAGS) -I../ -o $@ -o $@ jman/main_patchmeshes.c jman/patches2.c $(JMAN_SRC) $(LIBS) >$@.map + $(OBJDUMP) -d $@ > $@.dis + $(OBJCOPY) $@ -O binary $@.bin + $(OBJCOPY) -O srec $@ $@.srec + $(FLASHGEN) $@.bin $(ENDIAN_FLAGS) + cat $@.srec | packhex > $@.pack + +jman_polys.elf: $(JMAN_SRC) jman/main_polypin.c jman/polys.c libsys.a + $(CC) $(CFLAGS) -I../ -o $@ -o $@ jman/main_polypin.c jman/polys.c $(JMAN_SRC) $(LIBS) >$@.map + $(OBJDUMP) -d $@ > $@.dis + $(OBJCOPY) $@ -O binary $@.bin + $(OBJCOPY) -O srec $@ $@.srec + $(FLASHGEN) $@.bin $(ENDIAN_FLAGS) + cat $@.srec | packhex > $@.pack + +serdump.elf: serdump.c libsys.a + $(CC) $(CFLAGS) -O3 -o $@ -O2 serdump.c $(LIBS) >$@.map + $(OBJDUMP) -d $@ > $@.dis + $(OBJCOPY) $@ -O binary $@.bin + $(OBJCOPY) -O srec $@ $@.srec + $(FLASHGEN) $@.bin $(ENDIAN_FLAGS) + cat $@.srec | packhex > $@.pack + +pppi.elf: pppissue/test1.c pppissue/utils.c pppissue/pppd.h libsys.a + $(CC) $(CFLAGS) -O2 -o $@ -O2 pppissue/test1.c pppissue/utils.c $(LIBS) >$@.map + $(OBJDUMP) -d $@ > $@.dis + $(OBJCOPY) $@ -O binary $@.bin + $(OBJCOPY) -O srec $@ $@.srec + $(FLASHGEN) $@.bin $(ENDIAN_FLAGS) + cat $@.srec | packhex > $@.pack + +lwl.elf: lwl.c libsys.a + $(CC) $(CFLAGS) -O2 -o $@ lwl.c $(LIBS) >$@.map + $(OBJDUMP) -d $@ > $@.dis + $(OBJCOPY) $@ -O binary $@.bin + $(OBJCOPY) -O srec $@ $@.srec + $(FLASHGEN) $@.bin $(ENDIAN_FLAGS) + cat $@.srec | packhex > $@.pack + +ucb.elf: ucb.c libsys.a + $(CC) $(CFLAGS) -O2 -o $@ ucb.c $(LIBS) >$@.map + $(OBJDUMP) -d $@ > $@.dis + $(OBJCOPY) $@ -O binary $@.bin + $(OBJCOPY) -O srec $@ $@.srec + $(FLASHGEN) $@.bin $(ENDIAN_FLAGS) + cat $@.srec | packhex > $@.pack + +test_hpi.elf: hpi.c test_hpi.c cfiflash.c libsys.a + $(CC) $(CFLAGS) -o $@ -g hpi.c test_hpi.c cfiflash.c $(LIBS) >$@.map + $(OBJDUMP) -d $@ > $@.dis + $(OBJCOPY) $@ -O binary $@.bin + $(OBJCOPY) -O srec $@ $@.srec + $(FLASHGEN) $@.bin + cat $@.srec | packhex > $@.pack + +test_vga.elf: test_vga.c libsys.a + $(CC) $(CFLAGS) -o $@ test_vga.c $(LIBS) >$@.map + $(OBJDUMP) -d $@ > $@.dis + $(OBJCOPY) $@ -O binary $@.bin + $(OBJCOPY) -O srec $@ $@.srec + $(FLASHGEN) $@.bin $(ENDIAN_FLAGS) + cat $@.srec | packhex > $@.pack + +barcode.elf: barcode.c libsys.a + $(CC) $(CFLAGS) -o $@ barcode.c $(LIBS) >$@.map + $(OBJDUMP) -d $@ > $@.dis + $(OBJCOPY) $@ -O binary $@.bin + $(OBJCOPY) -O srec $@ $@.srec + $(FLASHGEN) $@.bin $(ENDIAN_FLAGS) + cat $@.srec | packhex > $@.pack + +lua.elf: lua_init.c libsys.a + $(CC) $(CFLAGS) -I./lua-5.1.4/etc -I./lua-5.1.4/src -o $@ lua_init.c $(LIBS) >$@.map + $(OBJDUMP) -d $@ > $@.dis + $(OBJCOPY) $@ -O binary $@.bin + $(OBJCOPY) -O srec $@ $@.srec + $(FLASHGEN) $@.bin $(ENDIAN_FLAGS) + cat $@.srec | packhex > $@.pack + +mandelbrot.elf: mandelbrot.c libsys.a + $(CC) $(CFLAGS) -o $@ mandelbrot.c $(LIBS) >$@.map + $(OBJDUMP) -d $@ > $@.dis + $(OBJCOPY) $@ -O binary $@.bin + $(OBJCOPY) -O srec $@ $@.srec + $(FLASHGEN) $@.bin $(ENDIAN_FLAGS) + cat $@.srec | packhex > $@.pack + +bogomips.elf: bogomips.c delay_mips.c libsys.a + $(CC) $(CFLAGS) -DHZ=1000 -o $@ bogomips.c delay_mips.c $(LIBS) >$@.map + $(OBJDUMP) -d $@ > $@.dis + $(OBJCOPY) $@ -O binary $@.bin + $(OBJCOPY) -O srec $@ $@.srec + $(FLASHGEN) $@.bin $(ENDIAN_FLAGS) + cat $@.srec | packhex > $@.pack + +test_asm.elf: test_asm.S libsys.a + $(CC) $(CFLAGS) -DHZ=1000 -o $@ test_asm.S $(LIBS) >$@.map + $(OBJDUMP) -d $@ > $@.dis + $(OBJCOPY) $@ -O binary $@.bin + $(OBJCOPY) -O srec $@ $@.srec + $(FLASHGEN) $@.bin $(ENDIAN_FLAGS) + cat $@.srec | packhex > $@.pack + +test_ac97.elf: test_ac97.c libsys.a + $(CC) $(CFLAGS) -o $@ test_ac97.c $(LIBS) >$@.map + $(OBJDUMP) -d $@ > $@.dis + $(OBJCOPY) $@ -O binary $@.bin + $(OBJCOPY) -O srec $@ $@.srec + $(FLASHGEN) $@.bin $(ENDIAN_FLAGS) + cat $@.srec | packhex > $@.pack + +test_dcache.elf: test_dcache.c libsys.a + $(CC) $(CFLAGS) -O0 -o $@ test_dcache.c $(LIBS) >$@.map + $(OBJDUMP) -d $@ > $@.dis + $(OBJCOPY) $@ -O binary $@.bin + $(OBJCOPY) -O srec $@ $@.srec + $(FLASHGEN) $@.bin $(ENDIAN_FLAGS) + cat $@.srec | packhex > $@.pack + +aes256_1.elf: aes256_1.c aes256.c aes256.h libsys.a + $(CC) $(CFLAGS) -O3 -o $@ aes256_1.c aes256.c $(LIBS) >$@.map + $(OBJDUMP) -d $@ > $@.dis + $(OBJCOPY) $@ -O binary $@.bin + $(OBJCOPY) -O srec $@ $@.srec + $(FLASHGEN) $@.bin $(ENDIAN_FLAGS) + cat $@.srec | packhex > $@.pack + +clean: + rm -rf *.a *.o *.bin *.map *.dis *.srec *.pack *.elf $(PROG) > /dev/null diff --git a/lib/CPUs/MIPS/bsp/examples/aes256.c b/lib/CPUs/MIPS/bsp/examples/aes256.c new file mode 100644 index 0000000..97a5136 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/aes256.c @@ -0,0 +1,359 @@ +/* +* Byte-oriented AES-256 implementation. +* All lookup tables replaced with 'on the fly' calculations. +* +* Copyright (c) 2007-2009 Ilya O. Levin, http://www.literatecode.com +* Other contributors: Hal Finney +* +* Permission to use, copy, modify, and distribute this software for any +* purpose with or without fee is hereby granted, provided that the above +* copyright notice and this permission notice appear in all copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +#include "aes256.h" + +#define F(x) (((x)<<1) ^ ((((x)>>7) & 1) * 0x1b)) +#define FD(x) (((x) >> 1) ^ (((x) & 1) ? 0x8d : 0)) + +#define BACK_TO_TABLES +#ifdef BACK_TO_TABLES + +const uint8_t sbox[256] = { + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, + 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, + 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, + 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, + 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, + 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, + 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, + 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, + 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, + 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, + 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, + 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, + 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, + 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, + 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, + 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, + 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 +}; +const uint8_t sboxinv[256] = { + 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, + 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, + 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, + 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, + 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, + 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, + 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, + 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, + 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, + 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, + 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, + 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, + 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, + 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, + 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, + 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, + 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, + 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, + 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, + 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, + 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, + 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, + 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, + 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, + 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, + 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, + 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, + 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, + 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, + 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, + 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d +}; + +#define rj_sbox(x) sbox[(x)] +#define rj_sbox_inv(x) sboxinv[(x)] + +#else /* tableless subroutines */ + +/* -------------------------------------------------------------------------- */ +uint8_t gf_alog(uint8_t x) // calculate anti-logarithm gen 3 +{ + uint8_t atb = 1, z; + + while (x--) {z = atb; atb <<= 1; if (z & 0x80) atb^= 0x1b; atb ^= z;} + + return atb; +} /* gf_alog */ + +/* -------------------------------------------------------------------------- */ +uint8_t gf_log(uint8_t x) // calculate logarithm gen 3 +{ + uint8_t atb = 1, i = 0, z; + + do { + if (atb == x) break; + z = atb; atb <<= 1; if (z & 0x80) atb^= 0x1b; atb ^= z; + } while (++i > 0); + + return i; +} /* gf_log */ + + +/* -------------------------------------------------------------------------- */ +uint8_t gf_mulinv(uint8_t x) // calculate multiplicative inverse +{ + return (x) ? gf_alog(255 - gf_log(x)) : 0; +} /* gf_mulinv */ + +/* -------------------------------------------------------------------------- */ +uint8_t rj_sbox(uint8_t x) +{ + uint8_t y, sb; + + sb = y = gf_mulinv(x); + y = (y<<1)|(y>>7); sb ^= y; y = (y<<1)|(y>>7); sb ^= y; + y = (y<<1)|(y>>7); sb ^= y; y = (y<<1)|(y>>7); sb ^= y; + + return (sb ^ 0x63); +} /* rj_sbox */ + +/* -------------------------------------------------------------------------- */ +uint8_t rj_sbox_inv(uint8_t x) +{ + uint8_t y, sb; + + y = x ^ 0x63; + sb = y = (y<<1)|(y>>7); + y = (y<<2)|(y>>6); sb ^= y; y = (y<<3)|(y>>5); sb ^= y; + + return gf_mulinv(sb); +} /* rj_sbox_inv */ + +#endif + +/* -------------------------------------------------------------------------- */ +uint8_t rj_xtime(uint8_t x) +{ + return (x & 0x80) ? ((x << 1) ^ 0x1b) : (x << 1); +} /* rj_xtime */ + +/* -------------------------------------------------------------------------- */ +void aes_subBytes(uint8_t *buf) +{ + register uint8_t i = 16; + + while (i--) buf[i] = rj_sbox(buf[i]); +} /* aes_subBytes */ + +/* -------------------------------------------------------------------------- */ +void aes_subBytes_inv(uint8_t *buf) +{ + register uint8_t i = 16; + + while (i--) buf[i] = rj_sbox_inv(buf[i]); +} /* aes_subBytes_inv */ + +/* -------------------------------------------------------------------------- */ +void aes_addRoundKey(uint8_t *buf, uint8_t *key) +{ + register uint8_t i = 16; + + while (i--) buf[i] ^= key[i]; +} /* aes_addRoundKey */ + +/* -------------------------------------------------------------------------- */ +void aes_addRoundKey_cpy(uint8_t *buf, uint8_t *key, uint8_t *cpk) +{ + register uint8_t i = 16; + + while (i--) buf[i] ^= (cpk[i] = key[i]), cpk[16+i] = key[16 + i]; +} /* aes_addRoundKey_cpy */ + + +/* -------------------------------------------------------------------------- */ +void aes_shiftRows(uint8_t *buf) +{ + register uint8_t i, j; /* to make it potentially parallelable :) */ + + i = buf[1]; buf[1] = buf[5]; buf[5] = buf[9]; buf[9] = buf[13]; buf[13] = i; + i = buf[10]; buf[10] = buf[2]; buf[2] = i; + j = buf[3]; buf[3] = buf[15]; buf[15] = buf[11]; buf[11] = buf[7]; buf[7] = j; + j = buf[14]; buf[14] = buf[6]; buf[6] = j; + +} /* aes_shiftRows */ + +/* -------------------------------------------------------------------------- */ +void aes_shiftRows_inv(uint8_t *buf) +{ + register uint8_t i, j; /* same as above :) */ + + i = buf[1]; buf[1] = buf[13]; buf[13] = buf[9]; buf[9] = buf[5]; buf[5] = i; + i = buf[2]; buf[2] = buf[10]; buf[10] = i; + j = buf[3]; buf[3] = buf[7]; buf[7] = buf[11]; buf[11] = buf[15]; buf[15] = j; + j = buf[6]; buf[6] = buf[14]; buf[14] = j; + +} /* aes_shiftRows_inv */ + +/* -------------------------------------------------------------------------- */ +void aes_mixColumns(uint8_t *buf) +{ + register uint8_t i, a, b, c, d, e; + + for (i = 0; i < 16; i += 4) + { + a = buf[i]; b = buf[i + 1]; c = buf[i + 2]; d = buf[i + 3]; + e = a ^ b ^ c ^ d; + buf[i] ^= e ^ rj_xtime(a^b); buf[i+1] ^= e ^ rj_xtime(b^c); + buf[i+2] ^= e ^ rj_xtime(c^d); buf[i+3] ^= e ^ rj_xtime(d^a); + } +} /* aes_mixColumns */ + +/* -------------------------------------------------------------------------- */ +void aes_mixColumns_inv(uint8_t *buf) +{ + register uint8_t i, a, b, c, d, e, x, y, z; + + for (i = 0; i < 16; i += 4) + { + a = buf[i]; b = buf[i + 1]; c = buf[i + 2]; d = buf[i + 3]; + e = a ^ b ^ c ^ d; + z = rj_xtime(e); + x = e ^ rj_xtime(rj_xtime(z^a^c)); y = e ^ rj_xtime(rj_xtime(z^b^d)); + buf[i] ^= x ^ rj_xtime(a^b); buf[i+1] ^= y ^ rj_xtime(b^c); + buf[i+2] ^= x ^ rj_xtime(c^d); buf[i+3] ^= y ^ rj_xtime(d^a); + } +} /* aes_mixColumns_inv */ + +/* -------------------------------------------------------------------------- */ +void aes_expandEncKey(uint8_t *k, uint8_t *rc) +{ + register uint8_t i; + + k[0] ^= rj_sbox(k[29]) ^ (*rc); + k[1] ^= rj_sbox(k[30]); + k[2] ^= rj_sbox(k[31]); + k[3] ^= rj_sbox(k[28]); + *rc = F( *rc); + + for(i = 4; i < 16; i += 4) k[i] ^= k[i-4], k[i+1] ^= k[i-3], + k[i+2] ^= k[i-2], k[i+3] ^= k[i-1]; + k[16] ^= rj_sbox(k[12]); + k[17] ^= rj_sbox(k[13]); + k[18] ^= rj_sbox(k[14]); + k[19] ^= rj_sbox(k[15]); + + for(i = 20; i < 32; i += 4) k[i] ^= k[i-4], k[i+1] ^= k[i-3], + k[i+2] ^= k[i-2], k[i+3] ^= k[i-1]; + +} /* aes_expandEncKey */ + +/* -------------------------------------------------------------------------- */ +void aes_expandDecKey(uint8_t *k, uint8_t *rc) +{ + uint8_t i; + + for(i = 28; i > 16; i -= 4) k[i+0] ^= k[i-4], k[i+1] ^= k[i-3], + k[i+2] ^= k[i-2], k[i+3] ^= k[i-1]; + + k[16] ^= rj_sbox(k[12]); + k[17] ^= rj_sbox(k[13]); + k[18] ^= rj_sbox(k[14]); + k[19] ^= rj_sbox(k[15]); + + for(i = 12; i > 0; i -= 4) k[i+0] ^= k[i-4], k[i+1] ^= k[i-3], + k[i+2] ^= k[i-2], k[i+3] ^= k[i-1]; + + *rc = FD(*rc); + k[0] ^= rj_sbox(k[29]) ^ (*rc); + k[1] ^= rj_sbox(k[30]); + k[2] ^= rj_sbox(k[31]); + k[3] ^= rj_sbox(k[28]); +} /* aes_expandDecKey */ + + +/* -------------------------------------------------------------------------- */ +void aes256_init(aes256_context *ctx, uint8_t *k) +{ + uint8_t rcon = 1; + register uint8_t i; + + for (i = 0; i < sizeof(ctx->key); i++) ctx->enckey[i] = ctx->deckey[i] = k[i]; + for (i = 8;--i;) aes_expandEncKey(ctx->deckey, &rcon); +} /* aes256_init */ + +/* -------------------------------------------------------------------------- */ +void aes256_done(aes256_context *ctx) +{ + register uint8_t i; + + for (i = 0; i < sizeof(ctx->key); i++) + ctx->key[i] = ctx->enckey[i] = ctx->deckey[i] = 0; +} /* aes256_done */ + +/* -------------------------------------------------------------------------- */ +void aes256_encrypt_ecb(aes256_context *ctx, uint8_t *buf) +{ + uint8_t i, rcon; + + aes_addRoundKey_cpy(buf, ctx->enckey, ctx->key); + for(i = 1, rcon = 1; i < 14; ++i) + { + aes_subBytes(buf); + aes_shiftRows(buf); + aes_mixColumns(buf); + if( i & 1 ) aes_addRoundKey( buf, &ctx->key[16]); + else aes_expandEncKey(ctx->key, &rcon), aes_addRoundKey(buf, ctx->key); + } + aes_subBytes(buf); + aes_shiftRows(buf); + aes_expandEncKey(ctx->key, &rcon); + aes_addRoundKey(buf, ctx->key); +} /* aes256_encrypt */ + +/* -------------------------------------------------------------------------- */ +void aes256_decrypt_ecb(aes256_context *ctx, uint8_t *buf) +{ + uint8_t i, rcon; + + aes_addRoundKey_cpy(buf, ctx->deckey, ctx->key); + aes_shiftRows_inv(buf); + aes_subBytes_inv(buf); + + for (i = 14, rcon = 0x80; --i;) + { + if( ( i & 1 ) ) + { + aes_expandDecKey(ctx->key, &rcon); + aes_addRoundKey(buf, &ctx->key[16]); + } + else aes_addRoundKey(buf, ctx->key); + aes_mixColumns_inv(buf); + aes_shiftRows_inv(buf); + aes_subBytes_inv(buf); + } + aes_addRoundKey( buf, ctx->key); +} /* aes256_decrypt */ diff --git a/lib/CPUs/MIPS/bsp/examples/aes256.h b/lib/CPUs/MIPS/bsp/examples/aes256.h new file mode 100644 index 0000000..c5a22ba --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/aes256.h @@ -0,0 +1,42 @@ +/* +* Byte-oriented AES-256 implementation. +* All lookup tables replaced with 'on the fly' calculations. +* +* Copyright (c) 2007-2009 Ilya O. Levin, http://www.literatecode.com +* Other contributors: Hal Finney +* +* Permission to use, copy, modify, and distribute this software for any +* purpose with or without fee is hereby granted, provided that the above +* copyright notice and this permission notice appear in all copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +#ifndef uint8_t +#define uint8_t unsigned char +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + typedef struct { + uint8_t key[32]; + uint8_t enckey[32]; + uint8_t deckey[32]; + } aes256_context; + + + void aes256_init(aes256_context *, uint8_t * /* key */); + void aes256_done(aes256_context *); + void aes256_encrypt_ecb(aes256_context *, uint8_t * /* plaintext */); + void aes256_decrypt_ecb(aes256_context *, uint8_t * /* cipertext */); + +#ifdef __cplusplus +} +#endif diff --git a/lib/CPUs/MIPS/bsp/examples/aes256_1.c b/lib/CPUs/MIPS/bsp/examples/aes256_1.c new file mode 100644 index 0000000..8a987b8 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/aes256_1.c @@ -0,0 +1,76 @@ +/* +* Byte-oriented AES-256 implementation. +* All lookup tables replaced with 'on the fly' calculations. +* +* Copyright (c) 2007 Ilya O. Levin, http://www.literatecode.com +* +* Permission to use, copy, modify, and distribute this software for any +* purpose with or without fee is hereby granted, provided that the above +* copyright notice and this permission notice appear in all copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +#include +#include +#include +#include +#include +#include "aes256.h" + +#ifndef NUM_BLOCKS +#define NUM_BLOCKS 10000 +#endif + +#define DUMP(s, i, buf, sz) {printf(s); \ + for (i = 0; i < (sz);i++) \ + printf("%02x ", buf[i]); \ + printf("\n");} + + +int main (int argc, char *argv[]) +{ + aes256_context ctx; + uint8_t key[32]; + uint8_t buf[16], i; + long start, end, j; + + /* put a test vector */ + for (i = 0; i < sizeof(buf);i++) buf[i] = i * 16 + i; + for (i = 0; i < sizeof(key);i++) key[i] = i; + + DUMP("txt: ", i, buf, sizeof(buf)); + DUMP("key: ", i, key, sizeof(key)); + printf("---\n"); + + aes256_init(&ctx, key); + start = clock(); + for (j=0; j < NUM_BLOCKS; j++) + { + aes256_encrypt_ecb(&ctx, buf); + } + end = clock(); + DUMP("enc: ", i, buf, sizeof(buf)); + + printf("Speed %f blocks/s\n", (float)j/((float)(end-start)/CLOCKS_PER_SEC)); + + aes256_init(&ctx, key); + start = clock(); + for (j=0; j < NUM_BLOCKS; j++) + { + aes256_decrypt_ecb(&ctx, buf); + } + end = clock(); + DUMP("dec: ", i, buf, sizeof(buf)); + + printf("Speed %f blocks/s\n", (float)j/((float)(end-start)/CLOCKS_PER_SEC)); + + aes256_done(&ctx); + + return 0; +} /* main */ diff --git a/lib/CPUs/MIPS/bsp/examples/barcode.c b/lib/CPUs/MIPS/bsp/examples/barcode.c new file mode 100644 index 0000000..e1dc1bc --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/barcode.c @@ -0,0 +1,358 @@ +#include +#include +#include +#include +#include +#include +#include + +#define CPU_FREQ_HZ 100000000 +#include "libsys.h" +#include "irq.h" + +UINT32 buffer[16384]; + +#define T_SAMPLE 5000 +#define TIMEOUT 1000 + +typedef struct _bar_t +{ + UINT32 T; + UINT32 black; +} bar_t; + +enum +{ + state_idle = 0, + state_sample, + state_finish +}; + +typedef struct _sbar_cand_t +{ + UINT32 T; + UINT32 is_primitive; +} bar_cand_t; + +bar_t bars[1024]; + +void bsort(float *pData, UINT32 len) +{ + float t; + int i, j; + + for(i=len-1; i>=0; i--) + { + for(j=1; j pData[j]) + { + t = pData[j-1]; + pData[j-1] = pData[j]; + pData[j] = t; + } + } + } +} + +typedef struct _smedian_t +{ + UINT32 N; + UINT32 is_dirty; + float *pBuf, *pSorted; + UINT32 w; + float median; +} median_t; + +void Median_init(median_t *pObj, UINT32 N, float init_val) +{ + int i; + pObj->pBuf = (float*)malloc(N*sizeof(float)); + pObj->pSorted = (float*)malloc(N*sizeof(float)); + for (i=0; i < N; i++) + pObj->pBuf[0] = init_val; + pObj->median = init_val; + pObj->is_dirty = 0; + pObj->w = 0; + pObj->N = N; +} + +void Median_free(median_t *pObj) +{ + if (pObj->pBuf) + free(pObj->pBuf); + + if (pObj->pSorted) + free(pObj->pSorted); + + pObj->pBuf = NULL; + pObj->pSorted = NULL; + +} + +void Median_value_add(median_t *pObj, float value) +{ + pObj->is_dirty = 1; + pObj->pBuf[pObj->w++] = value; + + if (pObj->w == pObj->N) + pObj->w = 0; + +} + +float Median_get(median_t *pObj) +{ + if (!pObj->is_dirty) + return pObj->median; + + memcpy(pObj->pSorted, pObj->pBuf, pObj->N*sizeof(float)); + + bsort(pObj->pSorted, pObj->N); + + if (pObj->N&1) + { + pObj->median = pObj->pSorted[(pObj->N-1)/2]; + } + else + { + pObj->median = 0.5f*(pObj->pSorted[pObj->N/2] + pObj->pSorted[pObj->N/2+1]); + } + + pObj->is_dirty = 0; + + return pObj->median; +} + +// ------------------------------------------------------------- +UINT32 detect_module(UINT32 T, UINT32 T0) +{ + UINT32 m, best_M; + float err, kc, best_err; + + best_err = 4.f; + best_M = 0; + + for (m=1; m < 5; m++) + { + kc = (float)T/(m*T0); + err = fabs(kc - 1); + + if (err < best_err) + { + best_M = m; + best_err = err; + } + } + + return best_M; +} + +void handler7(void) +{ + UINT32 volatile *pTim_ctrl = (UINT32*)SYS_ITIM_CTRL; + UINT32 volatile *pTim_stat = (UINT32*)SYS_ITIM_STAT; + UINT32 volatile *pPS20_stat = (UINT32*)SYS_PS2_0_STAT; + UINT32 volatile *pPS21_stat = (UINT32*)SYS_PS2_1_STAT; + static UINT32 state, bar_count; + static UINT32 timeout_count, timeout_reload; + static UINT32 white, pin_last, skip, start; + static UINT32 module_cnt_w, module_cnt_b, Tmod0_w, Tmod0_b, M, T0; + float ratio, error, kc; + UINT32 i; + static median_t med_b, med_w; + static bar_cand_t bc_b, bc_w; + static median_t speed_b, speed_w; + + if (*pTim_stat & 1) + { + *pTim_stat = 1; + white = ((*pPS20_stat & SYS_PS2_BIT_PIN_DATA) == 0); + + switch (state) + { + case state_idle: + timeout_reload = TIMEOUT; + if (white != pin_last) + { + if (white) + break; + + state = state_sample; + module_cnt_b = 0; + module_cnt_w = 0; + Tmod0_w = 0xFFFFFFFF; + Tmod0_b = 0xFFFFFFFF; + bar_count = 0; + Median_init(&med_b, 3, 0); + Median_init(&med_w, 3, 0); + Median_init(&speed_b, 3, 1); + Median_init(&speed_w, 3, 1); + } + break; + + case state_sample: + if (!timeout_count) + { + state = state_finish; + break; + } + + if (white) + { + module_cnt_w++; + } + else + { + module_cnt_b++; + } + if (white != pin_last) + { + if (pin_last) + { + if (bar_count < 10) + { + if (1.5*module_cnt_w < Tmod0_w) + { + Tmod0_w = module_cnt_w; + } + } + Median_value_add(&med_w, Tmod0_w); + + timeout_reload = 10*Tmod0_w; + bars[bar_count].T = module_cnt_w; + bars[bar_count].black = 0; + module_cnt_w = 0; + + } + else + { + if (bar_count < 10) + { + if (1.5*module_cnt_b < Tmod0_b) + { + Tmod0_b = module_cnt_b; + } + } + Median_value_add(&med_b, Tmod0_b); + + timeout_reload = 10*Tmod0_b; + bars[bar_count].T = module_cnt_b; + bars[bar_count].black = 1; + module_cnt_b = 0; + } + bar_count++; + + } + break; + + case state_finish: + printf("------------------------------------------------\n"); + printf(" Black White \n"); + skip = 0; + start = 1; + Tmod0_w = Median_get(&med_w); + Tmod0_b = Median_get(&med_b); + for (i=0; i < bar_count; i++) + { + if (bars[i].black) + { + T0 = Median_get(&med_b); + ratio = (float)bars[i].T/T0; + if (start) + { + if (ratio > 4) + { + skip = 1; + continue; + } + } + start = 0; + skip = 0; + M = detect_module(bars[i].T, T0); + kc = (float)bars[i].T/(M*T0); + error = kc - 1; + +// printf("M=%d, R=%2.2f, E=%+2.2f [%04d]", M, ratio, error, T0); +// if (M == 1) + Median_value_add(&med_b, (UINT32)(T0*kc)); + Median_value_add(&speed_b, (float)bars[i].T/(M*Tmod0_b)); + + printf("%06d %2.6f ", bars[i].T, Median_get(&speed_b)); + + } + else + { + if (skip) + continue; + + T0 = Median_get(&med_w); + ratio = (float)bars[i].T/T0; + if (ratio > 9) + { + start = 1; +// printf("\n"); +// printf("------------------------------------------------\n"); +// printf(" Black White \n"); + continue; + } + + + M = detect_module(bars[i].T, T0); + kc = (float)bars[i].T/(M*T0); + error = kc - 1; + +// printf(" M=%d, R=%2.2f, E=%+2.2f [%04d]", M, ratio, error, T0); +// if (M == 1) + Median_value_add(&med_w, (UINT32)(T0*kc)); + Median_value_add(&speed_w, (float)bars[i].T/(M*Tmod0_w)); + + printf("%06d %2.6f ", bars[i].T, Median_get(&speed_w)); + printf("\n"); + } + } + Median_free(&med_b); + Median_free(&med_w); + Median_free(&speed_b); + Median_free(&speed_w); + if (bar_count) + printf("\n"); + + state = state_idle; + break; + + } + if (white != pin_last) + timeout_count = timeout_reload; + + pin_last = white; + if (timeout_count) + timeout_count--; + + } +} + +int main(void) +{ + + int i; + UINT32 volatile *pTim_ctrl = (UINT32*)SYS_ITIM_CTRL; + UINT32 volatile *pTim_stat = (UINT32*)SYS_ITIM_STAT; + UINT32 volatile *pTim0_cnt = (UINT32*)SYS_ITIM0_CNT; + UINT32 volatile *pTim0_cmp = (UINT32*)SYS_ITIM0_CMP; + + *pTim0_cnt = 0; + *pTim0_cmp = (UINT32)T_SAMPLE; + *pTim_stat = 1; + *pTim_ctrl = 3; + + interrupt_register(7, (void*)handler7); + + printf("Jenners BarCoder\n"); + + interrupt_enable(7); + + while(1) + { + } + return 0; +} diff --git a/lib/CPUs/MIPS/bsp/examples/barcode.new.c b/lib/CPUs/MIPS/bsp/examples/barcode.new.c new file mode 100644 index 0000000..06f1152 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/barcode.new.c @@ -0,0 +1,322 @@ +#include +#include +#include +#include +#include +#include +#include + +#define CPU_FREQ_HZ 100000000 +#include "libsys.h" +#include "irq.h" + +UINT32 buffer[16384]; + +#define T_SAMPLE 5000 +#define TIMEOUT 1000 + +typedef struct _bar_t +{ + UINT32 T; + UINT32 black; +} bar_t; + +enum +{ + state_idle = 0, + state_sample, + state_finish +}; + +bar_t bars[1024]; + +void bsort(float *pData, UINT32 len) +{ + float t; + int i, j; + + for(i=len-1; i>=0; i--) + { + for(j=1; j pData[j]) + { + t = pData[j-1]; + pData[j-1] = pData[j]; + pData[j] = t; + } + } + } +} + +typedef struct _smedian_t +{ + UINT32 N; + UINT32 is_dirty; + float *pBuf, *pSorted; + UINT32 w; + float median; +} median_t; + +void Median_init(median_t *pObj, UINT32 N, float init_val) +{ + int i; + pObj->pBuf = (float*)malloc(N*sizeof(float)); + pObj->pSorted = (float*)malloc(N*sizeof(float)); + for (i=0; i < N; i++) + pObj->pBuf[0] = init_val; + pObj->median = init_val; + pObj->is_dirty = 0; + pObj->w = 0; + pObj->N = N; +} + +void Median_free(median_t *pObj) +{ + if (pObj->pBuf) + free(pObj->pBuf); + + if (pObj->pSorted) + free(pObj->pSorted); + + pObj->pBuf = NULL; + pObj->pSorted = NULL; + +} + +void Median_value_add(median_t *pObj, float value) +{ + pObj->is_dirty = 1; + pObj->pBuf[pObj->w++] = value; + + if (pObj->w == pObj->N) + pObj->w = 0; + +} + +float Median_get(median_t *pObj) +{ + if (!pObj->is_dirty) + return pObj->median; + + memcpy(pObj->pSorted, pObj->pBuf, pObj->N*sizeof(float)); + + bsort(pObj->pSorted, pObj->N); + + if (pObj->N&1) + { + pObj->median = pObj->pSorted[(pObj->N-1)/2]; + } + else + { + pObj->median = 0.5f*(pObj->pSorted[pObj->N/2] + pObj->pSorted[pObj->N/2+1]); + } + + pObj->is_dirty = 0; + + return pObj->median; +} + +// ------------------------------------------------------------- +UINT32 detect_module(UINT32 T, UINT32 *pBC) +{ + UINT32 m, best_M; + float err, kc, best_err; + + best_err = 4.f; + best_M = 0; + + for (m=0; m < 4; m++) + { + kc = (float)T/pBC[m]; + err = fabs(kc - 1); + + if (err < best_err) + { + best_M = m+1; + best_err = err; + } + } + + return best_M; +} + +void handler7(void) +{ + UINT32 volatile *pTim_ctrl = (UINT32*)SYS_ITIM_CTRL; + UINT32 volatile *pTim_stat = (UINT32*)SYS_ITIM_STAT; + UINT32 volatile *pPS20_stat = (UINT32*)SYS_PS2_0_STAT; + UINT32 volatile *pPS21_stat = (UINT32*)SYS_PS2_1_STAT; + static UINT32 state, bar_count; + static UINT32 timeout_count, timeout_reload; + static UINT32 white, pin_last, skip, start; + static UINT32 module_cnt_w, module_cnt_b, Tmod0_w, Tmod0_b, M, T0; + float ratio, error, kc; + UINT32 i, j; + static median_t med_b, med_w; + static UINT32 bc_b[4], bc_w[4]; + + if (*pTim_stat & 1) + { + *pTim_stat = 1; + white = ((*pPS20_stat & SYS_PS2_BIT_PIN_DATA) == 0); + + switch (state) + { + case state_idle: + timeout_reload = TIMEOUT; + if (white != pin_last) + { + if (white) + break; + + state = state_sample; + module_cnt_b = 0; + module_cnt_w = 0; + Tmod0_w = 0xFFFFFFFF; + Tmod0_b = 0xFFFFFFFF; + bar_count = 0; + Median_init(&med_b, 3, 1); + Median_init(&med_w, 3, 1); + } + break; + + case state_sample: + if (!timeout_count) + { + state = state_finish; + break; + } + + if (white) + { + module_cnt_w++; + } + else + { + module_cnt_b++; + } + if (white != pin_last) + { + if (pin_last) + { + if (bar_count < 10) + { + if (1.5*module_cnt_w < Tmod0_w) + { + Tmod0_w = module_cnt_w; + } + } + timeout_reload = 10*Tmod0_w; + bars[bar_count].T = module_cnt_w; + bars[bar_count].black = 0; + module_cnt_w = 0; + + } + else + { + if (bar_count < 10) + { + if (1.5*module_cnt_b < Tmod0_b) + { + Tmod0_b = module_cnt_b; + } + } + timeout_reload = 10*Tmod0_b; + bars[bar_count].T = module_cnt_b; + bars[bar_count].black = 1; + module_cnt_b = 0; + } + bar_count++; + + } + break; + + case state_finish: + printf("------------------------------------------------\n"); + printf(" Black White \n"); + skip = 0; + start = 1; + for (i=0; i < 4; i++) + { + bc_b[i] = (i+1)*Tmod0_b; + bc_w[i] = (i+1)*Tmod0_w; + } + for (i=0; i < bar_count; i++) + { + if (bars[i].black) + { + M = detect_module(bars[i].T, bc_b); + if (M) + { + kc = (float)bars[i].T/bc_b[M-1]; + error = kc - 1; + Median_value_add(&med_b, kc); + printf("M=%d, R=%2.2f, E=%+2.2f [%04d]", M, kc, error, bc_b[M-1]); + kc = Median_get(&med_b); + bc_b[M-1] = (UINT32)(kc*bc_b[M-1]); + } +// printf("%d", M); + + } + else + { + M = detect_module(bars[i].T, bc_w); + if (M) + { + kc = (float)bars[i].T/bc_w[M-1]; + error = kc - 1; + Median_value_add(&med_w, kc); + printf(" M=%d, R=%2.2f, E=%+2.2f [%04d]", M, kc, error, bc_w[M-1]); + kc = Median_get(&med_w); + bc_w[M-1] = (UINT32)(kc*bc_w[M-1]); + + } +// printf("%d", M); + printf("\n"); + } + } + Median_free(&med_b); + Median_free(&med_w); + if (bar_count) + printf("\n"); + + state = state_idle; + break; + + } + if (white != pin_last) + timeout_count = timeout_reload; + + pin_last = white; + if (timeout_count) + timeout_count--; + + } +} + +int main(void) +{ + + int i; + UINT32 volatile *pTim_ctrl = (UINT32*)SYS_ITIM_CTRL; + UINT32 volatile *pTim_stat = (UINT32*)SYS_ITIM_STAT; + UINT32 volatile *pTim0_cnt = (UINT32*)SYS_ITIM0_CNT; + UINT32 volatile *pTim0_cmp = (UINT32*)SYS_ITIM0_CMP; + + *pTim0_cnt = 0; + *pTim0_cmp = (UINT32)T_SAMPLE; + *pTim_stat = 1; + *pTim_ctrl = 3; + + interrupt_register(7, (void*)handler7); + + printf("Jenners BarCoder\n"); + + interrupt_enable(7); + + while(1) + { + } + return 0; +} diff --git a/lib/CPUs/MIPS/bsp/examples/basicmath_small.c b/lib/CPUs/MIPS/bsp/examples/basicmath_small.c new file mode 100644 index 0000000..049fea2 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/basicmath_small.c @@ -0,0 +1,84 @@ +#include "snipmath.h" +#include + +/* The printf's may be removed to isolate just the math calculations */ + +int main(void) +{ + double a1 = 1.0, b1 = -10.5, c1 = 32.0, d1 = -30.0; + double a2 = 1.0, b2 = -4.5, c2 = 17.0, d2 = -30.0; + double a3 = 1.0, b3 = -3.5, c3 = 22.0, d3 = -31.0; + double a4 = 1.0, b4 = -13.7, c4 = 1.0, d4 = -35.0; + double x[3]; + double X; + int solutions; + int i; + unsigned long l = 0x3fed0169L; + struct int_sqrt q; + long n = 0; + + /* solve soem cubic functions */ + printf("********* CUBIC FUNCTIONS ***********\n"); + /* should get 3 solutions: 2, 6 & 2.5 */ + SolveCubic(a1, b1, c1, d1, &solutions, x); + printf("Solutions:"); + for(i=0;i0;b1--) { + for(c1=5;c1<15;c1+=0.5) { + for(d1=-1;d1>-11;d1--) { + SolveCubic(a1, b1, c1, d1, &solutions, x); + printf("Solutions:"); + for(i=0;i +#include + +/* this should be approx 2 Bo*oMips to start (note initial shift), and will + * still work even if initially too large, it will just take slightly longer */ +unsigned long loops_per_jiffy = (1<<12); + +/* This is the number of bits of precision for the loops_per_jiffy. Each + * bit takes on average 1.5/HZ seconds. This (like the original) is a little + * better than 1% */ +#define LPS_PREC 8 + +extern void delay(unsigned int loops); + +//plagiarized straight from the 2.4 sources. +#ifdef NOMAIN +int calibrate_delay(void) +#else +int main(void) +#endif +{ + unsigned long ticks, loopbit; + int lps_precision = LPS_PREC; + + loops_per_jiffy = (1<<12); + + printf("Calibrating delay loop... "); + while (loops_per_jiffy <<= 1) { + /* wait for "start of" clock tick */ + ticks = clock(); + while (ticks == clock()) + /* nothing */; + /* Go .. */ + ticks = clock(); + delay(loops_per_jiffy); + ticks = clock() - ticks; + if (ticks) + break; + } + +/* Do a binary approximation to get loops_per_jiffy set to equal one clock + (up to lps_precision bits) */ + + loops_per_jiffy >>= 1; + loopbit = loops_per_jiffy; + while ( lps_precision-- && (loopbit >>= 1) ) { + loops_per_jiffy |= loopbit; + ticks = clock(); + while (ticks == clock()); + ticks = clock(); + delay(loops_per_jiffy); + if (clock() != ticks) /* longer than 1 tick */ + loops_per_jiffy &= ~loopbit; + } + + +/* Round the value and print it */ + printf("%lu.%02lu BogoMIPS\n", + loops_per_jiffy/(500000/HZ), + (loops_per_jiffy/(5000/HZ)) % 100); + + + return loops_per_jiffy; +} + diff --git a/lib/CPUs/MIPS/bsp/examples/cfiflash.c b/lib/CPUs/MIPS/bsp/examples/cfiflash.c new file mode 100644 index 0000000..bbfbe43 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/cfiflash.c @@ -0,0 +1,415 @@ +#include +#include +#include "libsys.h" +#include "cfiflash.h" + +UINT32 cfi_get_status(flash_t *pObj) +{ + volatile UINT32 *pF; + UINT32 status; + + pF = (UINT32*)pObj->pBase; + + *pF = 0x00700070; + + status = *pF; + + *pF = 0x00FF00FF; + + return status; + +} + +void cfi_init(flash_t *pObj, UINT32 base_addr) +{ + int i; + UINT8 *pInfo; + UINT32 endian; + UINT8 *pEndian; + + pObj->pBase = (void*)base_addr; + + pInfo = (UINT8*)&pObj->info; + for (i=0; i < sizeof(flash_info_t); i++) + { + pInfo[i] = 0; + } + pObj->eb = 0; + endian = 0x12345678; + pEndian = (UINT8*)&endian; + if (*pEndian == 0x12) + { + pObj->eb = 1; + } + +} + +UINT32 cfi_find(flash_t *pObj) +{ + int i; + volatile UINT32 *pF; + volatile UINT16 *pF16; +// UINT8 qry_ref[12] = {0x51, 0x00, 0x51, 0x00, 0x52, 0x00, 0x52, 0x00, 0x59, 0x00, 0x59, 0x00}; + UINT32 size; + + pF = (UINT32*)pObj->pBase; + pF16 = (UINT16*)pObj->pBase; + + // Look for flash + *pF = 0x00980098; +// for (i=0; i < sizeof(qry_ref); i++) +// if (((UINT8*)(&pF[0x10]))[i] != qry_ref[i]) +// return (UINT32)-1; + + *pF = 0x00FF00FF; + *pF = 0x00900090; + +/* + printf("ManID : %8.8X\n", (UINT32)pF[0]); + printf("Device code : %8.8X\n", (UINT32)pF[1]); + printf("Block info : %8.8X\n", (UINT32)pF[2]); + + printf("VCC(min) : %8.8X\n", (UINT32)pF[0x1B]); + printf("VCC(max) : %8.8X\n", (UINT32)pF[0x1C]); + printf("VPP(min) : %8.8X\n", (UINT32)pF[0x1D]); + printf("VPP(max) : %8.8X\n", (UINT32)pF[0x1E]); + printf("Device Layout : %8.8X\n", (UINT32)pF[0x27]); + printf("Interface type : %8.8X %8.8X\n", (UINT32)pF[0x28], (UINT32)pF[0x29]); + printf("Write buffer size : %8.8X %8.8X\n", (UINT32)pF[0x2A], (UINT32)pF[0x2B]); + printf("Num. erase blocks : %8.8X\n", (UINT32)pF[0x2C]); + printf("Erase block info : %8.8X %8.8X %8.8X %8.8X\n", (UINT32)pF[0x2D], (UINT32)pF[0x2E], (UINT32)pF[0x2F], (UINT32)pF[0x30]); +*/ + pObj->info.num_flash = 2; + pObj->info.if_width = 32; + size = (UINT32)pF16[2*0x27]; + pObj->info.flashsize = pObj->info.num_flash; + for (i=0; i < size; i++) + pObj->info.flashsize *= 2; + + size = (UINT32)(pF16[2*0x2B] << 8 | pF16[2*0x2A]); + pObj->info.wbuf_size = pObj->info.num_flash; + for (i=0; i < size; i++) + pObj->info.wbuf_size *= 2; + + pObj->info.nblocks = (UINT32)(pF16[2*0x2E] << 8 | pF16[2*0x2D]) + 1; + pObj->info.blocksize = pObj->info.num_flash * ((UINT32)(pF16[2*0x30] << 8 | pF16[2*0x2F]) * 256); + + *pF = 0x00FF00FF; + + return 0; +} + +UINT32 cfi_block_is_locked(flash_t *pObj, UINT32 word_index) +{ + volatile UINT32 *pF; + UINT32 status, block_index, block_mask; + UINT32 error; + + pF = (UINT32*)pObj->pBase; + + if (word_index >= (pObj->info.flashsize/4)) + return CFI_ERR_INVPARAM; + + block_mask = ((pObj->info.nblocks-1) << 16); + block_index = word_index & block_mask; + + *pF = 0x00900090; + + error = ((UINT32)pF[block_index+2] & 0x00010001) != 0; + *pF = 0x00FF00FF; + + return error; +} + +UINT32 cfi_block_erase(flash_t *pObj, UINT32 word_index) +{ + volatile UINT32 *pF; + UINT32 status, block_index, block_mask; + UINT32 error; + + pF = (UINT32*)pObj->pBase; + + if (word_index >= (pObj->info.flashsize/4)) + return CFI_ERR_INVPARAM; + + block_mask = ((pObj->info.nblocks-1) << 16); + block_index = word_index & block_mask; + + pF[block_index] = 0x00200020; + pF[block_index] = 0x00D000D0; + + error = 0; + do + { + status = pF[block_index]; + + } while((status & SR_BIT_ISMS) != SR_BIT_ISMS); + + if (status & (SR_BIT_ECLBS | SR_BIT_VPENS | SR_BIT_DPS)) + { + error = CFI_ERR_DEV_FAIL | status; + } + + pF[block_index] = 0x00FF00FF; + + return error; +} + +UINT32 cfi_block_lock(flash_t *pObj, UINT32 word_index) +{ + volatile UINT32 *pF; + UINT32 status, block_index, block_mask; + UINT32 error; + + pF = (UINT32*)pObj->pBase; + + if (word_index >= (pObj->info.flashsize/4)) + return CFI_ERR_INVPARAM; + + block_mask = ((pObj->info.nblocks-1) << 16); + block_index = word_index & block_mask; + + pF[block_index] = 0x00600060; + pF[block_index] = 0x00010001; + + error = 0; + do + { + status = pF[block_index]; + + } while((status & SR_BIT_ISMS) != SR_BIT_ISMS); + + if (status & (SR_BIT_PSLBS | SR_BIT_VPENS | SR_BIT_ECLBS)) + { + error = CFI_ERR_DEV_FAIL | status; + } + + pF[block_index] = 0x00FF00FF; + + return error; +} + +UINT32 cfi_block_unlock(flash_t *pObj, UINT32 word_index) +{ + volatile UINT32 *pF; + UINT32 status, block_index, block_mask; + UINT32 error; + + pF = (UINT32*)pObj->pBase; + + if (word_index >= (pObj->info.flashsize/4)) + return CFI_ERR_INVPARAM; + + block_mask = ((pObj->info.nblocks-1) << 16); + block_index = word_index & block_mask; + + pF[block_index] = 0x00600060; + pF[block_index] = 0x00D000D0; + + error = 0; + do + { + status = pF[block_index]; + + } while((status & SR_BIT_ISMS) != SR_BIT_ISMS); + + if (status & (SR_BIT_PSLBS | SR_BIT_VPENS | SR_BIT_ECLBS)) + { + error = CFI_ERR_DEV_FAIL | status; + } + + pF[block_index] = 0x00FF00FF; + + return error; +} + +UINT32 cfi_program_single(flash_t *pObj, UINT32 word_index, UINT32 word) +{ + volatile UINT32 *pF; + UINT32 status, error; + + pF = (UINT32*)pObj->pBase; + + if (word_index >= (pObj->info.flashsize/4)) + return CFI_ERR_INVPARAM; + + pF[word_index] = 0x00400040; + pF[word_index] = word; + + error = 0; + do + { + status = pF[word_index]; + + } while((status & SR_BIT_ISMS) != SR_BIT_ISMS); + + if (status & (SR_BIT_PSLBS | SR_BIT_VPENS | SR_BIT_DPS)) + { + error = CFI_ERR_DEV_FAIL | status; + } + + pF[word_index] = 0x00FF00FF; + + return error; + +} + +UINT32 cfi_program_multi(flash_t *pObj, UINT32 word_index, UINT32 *pWords, UINT32 num_words) +{ + int i, j, k; + volatile UINT32 *pF; + UINT32 status, bcurr, bnext, block_mask, nblock_write, nbuf_write; + UINT32 error; + + pF = (UINT32*)pObj->pBase; + + if (word_index >= (pObj->info.flashsize/4)) + return CFI_ERR_INVPARAM; + + block_mask = ((pObj->info.nblocks-1) << 16); + + k = 0; + while(num_words) + { + + bcurr = word_index & block_mask; + bnext = bcurr + (1 << 16); + nblock_write = bnext - word_index; + if (nblock_write > num_words) + nblock_write = num_words; + + while(nblock_write) + { + error = 0; + pF[bcurr] = 0x00E800E8; + do + { + status = pF[bcurr]; + + } while((status & SR_BIT_ISMS) != SR_BIT_ISMS); + if (status & (SR_BIT_PSLBS | SR_BIT_VPENS | SR_BIT_DPS)) + { + error = CFI_ERR_DEV_FAIL | status; + break; + } + + nbuf_write = nblock_write; + if (nblock_write > pObj->info.wbuf_size/4) + nbuf_write = pObj->info.wbuf_size/4; + + pF[bcurr] = (nbuf_write-1) << 16 | (nbuf_write-1); + + for (j=0; j < nbuf_write; j++) + pF[word_index+j] = pWords[k++]; + + word_index += j; + nblock_write -= j; + num_words -= j; + + error = 0; + pF[bcurr] = 0x00D000D0; + do + { + status = pF[bcurr]; + + } while((status & SR_BIT_ISMS) != SR_BIT_ISMS); + if (status & (SR_BIT_PSLBS | SR_BIT_VPENS | SR_BIT_DPS)) + { + error = CFI_ERR_DEV_FAIL | status; + break; + } + + pF[bcurr] = 0x00FF00FF; + } + + if (IS_ERROR(error)) + { + pF[bcurr] = 0x00FF00FF; + break; + } + bcurr = bnext; + } + + return error; + +} + +UINT32 flash_find(flash_t *pObj, UINT32 base_addr) +{ + cfi_init(pObj, base_addr); + return cfi_find(pObj); +} + +UINT32 flash_erase(flash_t *pObj, UINT32 offset, UINT32 size) +{ + int i; + UINT32 offset_end, error; + + if (size % 4) + size = 4*(size/4 + 1); + + offset_end = offset + size; + + for (i=offset; i < offset_end; i += pObj->info.blocksize) + { + if (cfi_block_is_locked(pObj, i/4)) + { + error = cfi_block_unlock(pObj, i/4); + if (IS_ERROR(error)) + break; + } + error = cfi_block_erase(pObj, i/4); + if (IS_ERROR(error)) + break; + } + + return error; + +} + +UINT32 flash_program(flash_t *pObj, UINT32 offset, UINT8 *pData, UINT32 size) +{ + if (size % 4) + size = 4*(size/4 + 1); + + return cfi_program_multi(pObj, offset/4, (UINT32*)pData, size/4); +} + +UINT32 flash_verify(flash_t *pObj, UINT32 offset, UINT8 *pData, UINT32 size) +{ + int i; + UINT8 *pF; + + pF = (UINT8*)(pObj->pBase + offset); + + for (i=0; i < size; i++) + if (pF[i] != pData[i]) + return CFI_ERR_VFY_FAIL; + + return 0; +} + +UINT32 flash_get_blocknum_by_offset(flash_t *pObj, UINT32 offset) +{ + UINT32 blocknum; + + blocknum = offset/pObj->info.blocksize; + if (offset%pObj->info.blocksize) + blocknum++; + + return blocknum; +} + +UINT32 flash_get_offset_by_blocknum(flash_t *pObj, UINT32 blocknum) +{ + if (blocknum >= pObj->info.nblocks) + blocknum = pObj->info.nblocks - 1; + + return blocknum*pObj->info.blocksize; +} + +UINT32 flash_get_offset_blockaligned(flash_t *pObj, UINT32 offset) +{ + return flash_get_blocknum_by_offset(pObj, offset) * pObj->info.blocksize; +} + diff --git a/lib/CPUs/MIPS/bsp/examples/cfiflash.h b/lib/CPUs/MIPS/bsp/examples/cfiflash.h new file mode 100644 index 0000000..1233642 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/cfiflash.h @@ -0,0 +1,58 @@ +/************************************************************************/ +#ifndef CFIFLASH_H +#define CFIFLASH_H + +#include "libsys.h" + +#define SR_BIT_DPS 0x00020002 +#define SR_BIT_PSS 0x00040004 +#define SR_BIT_VPENS 0x00080008 +#define SR_BIT_PSLBS 0x00100010 +#define SR_BIT_ECLBS 0x00200020 +#define SR_BIT_ESS 0x00400040 +#define SR_BIT_ISMS 0x00800080 + +#define CFI_ERR_BASE (LSYS_ERR_BASE + 0x00100000) +#define CFI_ERR_GENERAL (CFI_ERR_BASE + 0) +#define CFI_ERR_NOTFOUND (CFI_ERR_BASE + 1) +#define CFI_ERR_INVPARAM (CFI_ERR_BASE + 2) +#define CFI_ERR_VFY_FAIL (CFI_ERR_BASE + 3) +#define CFI_ERR_DEV_FAIL (CFI_ERR_BASE + 0x10000000) + +typedef struct _sflash_info_t +{ + UINT32 flashsize; + UINT32 blocksize; + UINT32 nblocks; + UINT32 wbuf_size; + UINT32 if_width; + UINT32 num_flash; + +} flash_info_t; + +typedef struct _sflash_t +{ + void *pBase; + UINT32 eb; + flash_info_t info; + +} flash_t; + +void cfi_init(flash_t *pObj, UINT32 base_addr); +UINT32 cfi_find(flash_t *pObj); +UINT32 cfi_block_is_locked(flash_t *pObj, UINT32 word_index); +UINT32 cfi_block_erase(flash_t *pObj, UINT32 word_index); +UINT32 cfi_block_lock(flash_t *pObj, UINT32 word_index); +UINT32 cfi_block_unlock(flash_t *pObj, UINT32 word_index); +UINT32 cfi_program_single(flash_t *pObj, UINT32 word_index, UINT32 word); +UINT32 cfi_program_multi(flash_t *pObj, UINT32 word_index, UINT32 *pWords, UINT32 num_words); + +UINT32 flash_get_offset_by_blocknum(flash_t *pObj, UINT32 blocknum); +UINT32 flash_get_blocknum_by_offset(flash_t *pObj, UINT32 offset); +UINT32 flash_get_offset_blockaligned(flash_t *pObj, UINT32 offset); +UINT32 flash_find(flash_t *pObj, UINT32 base_addr); +UINT32 flash_erase(flash_t *pObj, UINT32 offset, UINT32 size); +UINT32 flash_program(flash_t *pObj, UINT32 offset, UINT8 *pData, UINT32 size); +UINT32 flash_verify(flash_t *pObj, UINT32 offset, UINT8 *pData, UINT32 size); + +#endif // CFIFLASH_H diff --git a/lib/CPUs/MIPS/bsp/examples/crc32.c b/lib/CPUs/MIPS/bsp/examples/crc32.c new file mode 100644 index 0000000..6f63429 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/crc32.c @@ -0,0 +1,54 @@ +#include + +unsigned long MakeCRC32(char *data, unsigned int len, unsigned int CRC) +{ + /* ======================================================================== + * Table of CRC-32's of all single-byte values (made by makecrc.c) + */ + unsigned long crc_32_tab[] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L, + 0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L, + 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, + 0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L, + 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, + 0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL, + 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, + 0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L, + 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, + 0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L, + 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, + 0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L, + 0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, + 0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L, + 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, + 0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L, + 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, + 0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 0x4669be79L, + 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, + 0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL, + 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, + 0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L, + 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, + 0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL, + 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL, + 0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL + }; + + if (data == NULL) + return 0; + + CRC = ~CRC; + while (len --) + { + CRC = crc_32_tab[((unsigned char) CRC ^ *data) & 0xFF] ^ (CRC >> 8); + data ++; + } + + return ~CRC; +} diff --git a/lib/CPUs/MIPS/bsp/examples/crc32.h b/lib/CPUs/MIPS/bsp/examples/crc32.h new file mode 100644 index 0000000..04687b0 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/crc32.h @@ -0,0 +1,13 @@ +// CRC32 function +// To create a CRC from a new buffer, use this: +// crc = MakeCRC32(mydata, data_len, 0); +// If you need to continue the CRC (e.g. your data is in multiple buffers), +// continue like this: +// crc = MakeCRC32(moredata, more_len, crc); +// +// Your desired CRC should be the complement of the CRC generated by +// MakeCRC32: +// desired = crc +// desired - crc = 0 + +unsigned long MakeCRC32(char *data, unsigned int len, unsigned long CRC); diff --git a/lib/CPUs/MIPS/bsp/examples/cubic.c b/lib/CPUs/MIPS/bsp/examples/cubic.c new file mode 100644 index 0000000..7740eb2 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/cubic.c @@ -0,0 +1,64 @@ +/* +++Date last modified: 05-Jul-1997 */ + +/* +** CUBIC.C - Solve a cubic polynomial +** public domain by Ross Cottrell +*/ + +#include +#include +#include "snipmath.h" + +void SolveCubic(double a, + double b, + double c, + double d, + int *solutions, + double *x) +{ + long double a1 = b/a, a2 = c/a, a3 = d/a; + long double Q = (a1*a1 - 3.0*a2)/9.0; + long double R = (2.0*a1*a1*a1 - 9.0*a1*a2 + 27.0*a3)/54.0; + double R2_Q3 = R*R - Q*Q*Q; + + double theta; + + if (R2_Q3 <= 0) + { + *solutions = 3; + theta = acos(R/sqrt(Q*Q*Q)); + x[0] = -2.0*sqrt(Q)*cos(theta/3.0) - a1/3.0; + x[1] = -2.0*sqrt(Q)*cos((theta+2.0*PI)/3.0) - a1/3.0; + x[2] = -2.0*sqrt(Q)*cos((theta+4.0*PI)/3.0) - a1/3.0; + } + else + { + *solutions = 1; + x[0] = pow(sqrt(R2_Q3)+fabs(R), 1/3.0); + x[0] += Q/x[0]; + x[0] *= (R < 0.0) ? 1 : -1; + x[0] -= a1/3.0; + } +} + +#ifdef TEST + +int main(void) +{ + double a1 = 1.0, b1 = -10.5, c1 = 32.0, d1 = -30.0; + double a2 = 1.0, b2 = -4.5, c2 = 17.0, d2 = -30.0; + double x[3]; + int solutions; + + SolveCubic(a1, b1, c1, d1, &solutions, x); + + /* should get 3 solutions: 2, 6 & 2.5 */ + + SolveCubic(a2, b2, c2, d2, &solutions, x); + + /* should get 1 solution: 2.5 */ + + return 0; +} + +#endif /* TEST */ diff --git a/lib/CPUs/MIPS/bsp/examples/delay_mips.c b/lib/CPUs/MIPS/bsp/examples/delay_mips.c new file mode 100644 index 0000000..133a176 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/delay_mips.c @@ -0,0 +1,15 @@ +// MIPS delay. + +void __inline__ delay(int loops) +{ + __asm + ( + ".set noreorder\n" + "1:bnez %[loops], 1b\n" + "addiu %[loops], -1\n" + ".set reorder\n" + : + : [loops] "r" (loops) + ); +} + diff --git a/lib/CPUs/MIPS/bsp/examples/demo.c b/lib/CPUs/MIPS/bsp/examples/demo.c new file mode 100644 index 0000000..e3fc38a --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/demo.c @@ -0,0 +1,67 @@ +/* +* Byte-oriented AES-256 implementation. +* All lookup tables replaced with 'on the fly' calculations. +* +* Copyright (c) 2007 Ilya O. Levin, http://www.literatecode.com +* +* Permission to use, copy, modify, and distribute this software for any +* purpose with or without fee is hereby granted, provided that the above +* copyright notice and this permission notice appear in all copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +#include +#include +#include +#include +#include +#include "aes256.h" + +#define DUMP(s, i, buf, sz) {printf(s); \ + for (i = 0; i < (sz);i++) \ + printf("%02x ", buf[i]); \ + printf("\n");} + + +int main (int argc, char *argv[]) +{ + aes256_context ctx; + uint8_t key[32]; + uint8_t buf[16], i; + long start, end, j; + + /* put a test vector */ + for (i = 0; i < sizeof(buf);i++) buf[i] = i * 16 + i; + for (i = 0; i < sizeof(key);i++) key[i] = i; + + DUMP("txt: ", i, buf, sizeof(buf)); + DUMP("key: ", i, key, sizeof(key)); + printf("---\n"); + + aes256_init(&ctx, key); + start = clock(); + for (j=0; j < 1000; j++) + { + aes256_encrypt_ecb(&ctx, buf); + } + end = clock(); + + printf("Speed %f blocks/s\n", (float)j/((float)(end-start)/CLOCKS_PER_SEC)); + + DUMP("enc: ", i, buf, sizeof(buf)); + printf("tst: 8e a2 b7 ca 51 67 45 bf ea fc 49 90 4b 49 60 89\n"); + + aes256_init(&ctx, key); + aes256_decrypt_ecb(&ctx, buf); + DUMP("dec: ", i, buf, sizeof(buf)); + + aes256_done(&ctx); + + return 0; +} /* main */ diff --git a/lib/CPUs/MIPS/bsp/examples/dhry.h b/lib/CPUs/MIPS/bsp/examples/dhry.h new file mode 100644 index 0000000..c8d8f0a --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/dhry.h @@ -0,0 +1,430 @@ +/* + **************************************************************************** + * + * "DHRYSTONE" Benchmark Program + * ----------------------------- + * + * Version: C, Version 2.1 + * + * File: dhry.h (part 1 of 3) + * + * Date: May 25, 1988 + * + * Author: Reinhold P. Weicker + * Siemens AG, E STE 35 + * Postfach 3240 + * 8520 Erlangen + * Germany (West) + * Phone: [xxx-49]-9131-7-20330 + * (8-17 Central European Time) + * Usenet: ..!mcvax!unido!estevax!weicker + * + * Original Version (in Ada) published in + * "Communications of the ACM" vol. 27., no. 10 (Oct. 1984), + * pp. 1013 - 1030, together with the statistics + * on which the distribution of statements etc. is based. + * + * In this C version, the following C library functions are used: + * - strcpy, strcmp (inside the measurement loop) + * - printf, scanf (outside the measurement loop) + * In addition, Berkeley UNIX system calls "times ()" or "time ()" + * are used for execution time measurement. For measurements + * on other systems, these calls have to be changed. + * + * Collection of Results: + * Reinhold Weicker (address see above) and + * + * Rick Richardson + * PC Research. Inc. + * 94 Apple Orchard Drive + * Tinton Falls, NJ 07724 + * Phone: (201) 389-8963 (9-17 EST) + * Usenet: ...!uunet!pcrat!rick + * + * Please send results to Rick Richardson and/or Reinhold Weicker. + * Complete information should be given on hardware and software used. + * Hardware information includes: Machine type, CPU, type and size + * of caches; for microprocessors: clock frequency, memory speed + * (number of wait states). + * Software information includes: Compiler (and runtime library) + * manufacturer and version, compilation switches, OS version. + * The Operating System version may give an indication about the + * compiler; Dhrystone itself performs no OS calls in the measurement loop. + * + * The complete output generated by the program should be mailed + * such that at least some checks for correctness can be made. + * + *************************************************************************** + * + * History: This version C/2.1 has been made for two reasons: + * + * 1) There is an obvious need for a common C version of + * Dhrystone, since C is at present the most popular system + * programming language for the class of processors + * (microcomputers, minicomputers) where Dhrystone is used most. + * There should be, as far as possible, only one C version of + * Dhrystone such that results can be compared without + * restrictions. In the past, the C versions distributed + * by Rick Richardson (Version 1.1) and by Reinhold Weicker + * had small (though not significant) differences. + * + * 2) As far as it is possible without changes to the Dhrystone + * statistics, optimizing compilers should be prevented from + * removing significant statements. + * + * This C version has been developed in cooperation with + * Rick Richardson (Tinton Falls, NJ), it incorporates many + * ideas from the "Version 1.1" distributed previously by + * him over the UNIX network Usenet. + * I also thank Chaim Benedelac (National Semiconductor), + * David Ditzel (SUN), Earl Killian and John Mashey (MIPS), + * Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley) + * for their help with comments on earlier versions of the + * benchmark. + * + * Changes: In the initialization part, this version follows mostly + * Rick Richardson's version distributed via Usenet, not the + * version distributed earlier via floppy disk by Reinhold Weicker. + * As a concession to older compilers, names have been made + * unique within the first 8 characters. + * Inside the measurement loop, this version follows the + * version previously distributed by Reinhold Weicker. + * + * At several places in the benchmark, code has been added, + * but within the measurement loop only in branches that + * are not executed. The intention is that optimizing compilers + * should be prevented from moving code out of the measurement + * loop, or from removing code altogether. Since the statements + * that are executed within the measurement loop have NOT been + * changed, the numbers defining the "Dhrystone distribution" + * (distribution of statements, operand types and locality) + * still hold. Except for sophisticated optimizing compilers, + * execution times for this version should be the same as + * for previous versions. + * + * Since it has proven difficult to subtract the time for the + * measurement loop overhead in a correct way, the loop check + * has been made a part of the benchmark. This does have + * an impact - though a very minor one - on the distribution + * statistics which have been updated for this version. + * + * All changes within the measurement loop are described + * and discussed in the companion paper "Rationale for + * Dhrystone version 2". + * + * Because of the self-imposed limitation that the order and + * distribution of the executed statements should not be + * changed, there are still cases where optimizing compilers + * may not generate code for some statements. To a certain + * degree, this is unavoidable for small synthetic benchmarks. + * Users of the benchmark are advised to check code listings + * whether code is generated for all statements of Dhrystone. + * + * Version 2.1 is identical to version 2.0 distributed via + * the UNIX network Usenet in March 1988 except that it corrects + * some minor deficiencies that were found by users of version 2.0. + * The only change within the measurement loop is that a + * non-executed "else" part was added to the "if" statement in + * Func_3, and a non-executed "else" part removed from Proc_3. + * + *************************************************************************** + * + * Defines: The following "Defines" are possible: + * -DREG=register (default: Not defined) + * As an approximation to what an average C programmer + * might do, the "register" storage class is applied + * (if enabled by -DREG=register) + * - for local variables, if they are used (dynamically) + * five or more times + * - for parameters if they are used (dynamically) + * six or more times + * Note that an optimal "register" strategy is + * compiler-dependent, and that "register" declarations + * do not necessarily lead to faster execution. + * -DNOSTRUCTASSIGN (default: Not defined) + * Define if the C compiler does not support + * assignment of structures. + * -DNOENUMS (default: Not defined) + * Define if the C compiler does not support + * enumeration types. + * -DTIMES (default) + * -DTIME + * The "times" function of UNIX (returning process times) + * or the "time" function (returning wallclock time) + * is used for measurement. + * For single user machines, "time ()" is adequate. For + * multi-user machines where you cannot get single-user + * access, use the "times ()" function. If you have + * neither, use a stopwatch in the dead of night. + * "printf"s are provided marking the points "Start Timer" + * and "Stop Timer". DO NOT use the UNIX "time(1)" + * command, as this will measure the total time to + * run this program, which will (erroneously) include + * the time to allocate storage (malloc) and to perform + * the initialization. + * -DHZ=nnn + * In Berkeley UNIX, the function "times" returns process + * time in 1/HZ seconds, with HZ = 60 for most systems. + * CHECK YOUR SYSTEM DESCRIPTION BEFORE YOU JUST APPLY + * A VALUE. + * + *************************************************************************** + * + * Compilation model and measurement (IMPORTANT): + * + * This C version of Dhrystone consists of three files: + * - dhry.h (this file, containing global definitions and comments) + * - dhry_1.c (containing the code corresponding to Ada package Pack_1) + * - dhry_2.c (containing the code corresponding to Ada package Pack_2) + * + * The following "ground rules" apply for measurements: + * - Separate compilation + * - No procedure merging + * - Otherwise, compiler optimizations are allowed but should be indicated + * - Default results are those without register declarations + * See the companion paper "Rationale for Dhrystone Version 2" for a more + * detailed discussion of these ground rules. + * + * For 16-Bit processors (e.g. 80186, 80286), times for all compilation + * models ("small", "medium", "large" etc.) should be given if possible, + * together with a definition of these models for the compiler system used. + * + ************************************************************************** + * + * Dhrystone (C version) statistics: + * + * [Comment from the first distribution, updated for version 2. + * Note that because of language differences, the numbers are slightly + * different from the Ada version.] + * + * The following program contains statements of a high level programming + * language (here: C) in a distribution considered representative: + * + * assignments 52 (51.0 %) + * control statements 33 (32.4 %) + * procedure, function calls 17 (16.7 %) + * + * 103 statements are dynamically executed. The program is balanced with + * respect to the three aspects: + * + * - statement type + * - operand type + * - operand locality + * operand global, local, parameter, or constant. + * + * The combination of these three aspects is balanced only approximately. + * + * 1. Statement Type: + * ----------------- number + * + * V1 = V2 9 + * (incl. V1 = F(..) + * V = Constant 12 + * Assignment, 7 + * with array element + * Assignment, 6 + * with record component + * -- + * 34 34 + * + * X = Y +|-|"&&"|"|" Z 5 + * X = Y +|-|"==" Constant 6 + * X = X +|- 1 3 + * X = Y *|/ Z 2 + * X = Expression, 1 + * two operators + * X = Expression, 1 + * three operators + * -- + * 18 18 + * + * if .... 14 + * with "else" 7 + * without "else" 7 + * executed 3 + * not executed 4 + * for ... 7 | counted every time + * while ... 4 | the loop condition + * do ... while 1 | is evaluated + * switch ... 1 + * break 1 + * declaration with 1 + * initialization + * -- + * 34 34 + * + * P (...) procedure call 11 + * user procedure 10 + * library procedure 1 + * X = F (...) + * function call 6 + * user function 5 + * library function 1 + * -- + * 17 17 + * --- + * 103 + * + * The average number of parameters in procedure or function calls + * is 1.82 (not counting the function values aX * + * + * 2. Operators + * ------------ + * number approximate + * percentage + * + * Arithmetic 32 50.8 + * + * + 21 33.3 + * - 7 11.1 + * * 3 4.8 + * / (int div) 1 1.6 + * + * Comparison 27 42.8 + * + * == 9 14.3 + * /= 4 6.3 + * > 1 1.6 + * < 3 4.8 + * >= 1 1.6 + * <= 9 14.3 + * + * Logic 4 6.3 + * + * && (AND-THEN) 1 1.6 + * | (OR) 1 1.6 + * ! (NOT) 2 3.2 + * + * -- ----- + * 63 100.1 + * + * + * 3. Operand Type (counted once per operand reference): + * --------------- + * number approximate + * percentage + * + * Integer 175 72.3 % + * Character 45 18.6 % + * Pointer 12 5.0 % + * String30 6 2.5 % + * Array 2 0.8 % + * Record 2 0.8 % + * --- ------- + * 242 100.0 % + * + * When there is an access path leading to the final operand (e.g. a record + * component), only the final data type on the access path is counted. + * + * + * 4. Operand Locality: + * ------------------- + * number approximate + * percentage + * + * local variable 114 47.1 % + * global variable 22 9.1 % + * parameter 45 18.6 % + * value 23 9.5 % + * reference 22 9.1 % + * function result 6 2.5 % + * constant 55 22.7 % + * --- ------- + * 242 100.0 % + * + * + * The program does not compute anything meaningful, but it is syntactically + * and semantically correct. All variables have a value assigned to them + * before they are used as a source operand. + * + * There has been no explicit effort to account for the effects of a + * cache, or to balance the use of long or short displacements for code or + * data. + * + *************************************************************************** + */ + +/* Compiler and system dependent definitions: */ + +#ifndef TIME +#undef TIMES +#define TIMES +#endif + /* Use times(2) time function unless */ + /* explicitly defined otherwise */ +#ifdef MSC_CLOCK +#undef HZ +#undef TIMES +#include +#define HZ CLK_TCK +#endif + /* Use Microsoft C hi-res clock */ + +#ifdef TIMES +#include +#include + /* for "times" */ +#endif + +#define Mic_secs_Per_Second 1000000.0 + /* Berkeley UNIX C returns process times in seconds/HZ */ + +#ifdef NOSTRUCTASSIGN +#define structassign(d, s) memcpy(&(d), &(s), sizeof(d)) +#else +#define structassign(d, s) d = s +#endif + +#ifdef NOENUM +#define Ident_1 0 +#define Ident_2 1 +#define Ident_3 2 +#define Ident_4 3 +#define Ident_5 4 + typedef int Enumeration; +#else + typedef enum {Ident_1, Ident_2, Ident_3, Ident_4, Ident_5} + Enumeration; +#endif + /* for boolean and enumeration types in Ada, Pascal */ + +/* General definitions: */ + +#include + /* for strcpy, strcmp */ + +#define Null 0 + /* Value of a Null pointer */ +#define true 1 +#define false 0 + +typedef int One_Thirty; +typedef int One_Fifty; +typedef char Capital_Letter; +typedef int Boolean; +typedef char Str_30 [31]; +typedef int Arr_1_Dim [50]; +typedef int Arr_2_Dim [50] [50]; + +typedef struct record + { + struct record *Ptr_Comp; + Enumeration Discr; + union { + struct { + Enumeration Enum_Comp; + int Int_Comp; + char Str_Comp [31]; + } var_1; + struct { + Enumeration E_Comp_2; + char Str_2_Comp [31]; + } var_2; + struct { + char Ch_1_Comp; + char Ch_2_Comp; + } var_3; + } variant; + } Rec_Type, *Rec_Pointer; + + diff --git a/lib/CPUs/MIPS/bsp/examples/dhry_1.c b/lib/CPUs/MIPS/bsp/examples/dhry_1.c new file mode 100644 index 0000000..f7b8373 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/dhry_1.c @@ -0,0 +1,402 @@ +/* + **************************************************************************** + * + * "DHRYSTONE" Benchmark Program + * ----------------------------- + * + * Version: C, Version 2.1 + * + * File: dhry_1.c (part 2 of 3) + * + * Date: May 25, 1988 + * + * Author: Reinhold P. Weicker + * + **************************************************************************** + */ + +#include "dhry.h" + +/* Global Variables: */ + +Rec_Pointer Ptr_Glob, + Next_Ptr_Glob; +int Int_Glob; +Boolean Bool_Glob; +char Ch_1_Glob, + Ch_2_Glob; +int Arr_1_Glob [50]; +int Arr_2_Glob [50] [50]; + +extern char *malloc (); +Enumeration Func_1 (); + /* forward declaration necessary since Enumeration may not simply be int */ + +#ifndef REG + Boolean Reg = false; +#define REG + /* REG becomes defined as empty */ + /* i.e. no register variables */ +#else + Boolean Reg = true; +#endif + +/* variables for time measurement: */ + +#ifdef TIMES +struct tms time_info; + /* see library function "times" */ +#define Too_Small_Time (2*HZ) + /* Measurements should last at least about 2 seconds */ +#endif +#ifdef TIME +extern long time(); + /* see library function "time" */ +#define Too_Small_Time 2 + /* Measurements should last at least 2 seconds */ +#endif +#ifdef MSC_CLOCK +extern clock_t clock(); +#define Too_Small_Time (2*HZ) +#endif + +long Begin_Time, + End_Time, + User_Time; +float Microseconds, + Dhrystones_Per_Second; + +/* end of variables for time measurement */ + + +main () +/*****/ + + /* main program, corresponds to procedures */ + /* Main and Proc_0 in the Ada version */ +{ + One_Fifty Int_1_Loc; + REG One_Fifty Int_2_Loc; + One_Fifty Int_3_Loc; + REG char Ch_Index; + Enumeration Enum_Loc; + Str_30 Str_1_Loc; + Str_30 Str_2_Loc; + REG int Run_Index; + REG int Number_Of_Runs; + + /* Initializations */ + + Next_Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type)); + Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type)); + + Ptr_Glob->Ptr_Comp = Next_Ptr_Glob; + Ptr_Glob->Discr = Ident_1; + Ptr_Glob->variant.var_1.Enum_Comp = Ident_3; + Ptr_Glob->variant.var_1.Int_Comp = 40; + strcpy (Ptr_Glob->variant.var_1.Str_Comp, + "DHRYSTONE PROGRAM, SOME STRING"); + strcpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING"); + + Arr_2_Glob [8][7] = 10; + /* Was missing in published program. Without this statement, */ + /* Arr_2_Glob [8][7] would have an undefined value. */ + /* Warning: With 16-Bit processors and Number_Of_Runs > 32000, */ + /* overflow may occur for this array element. */ + + /* + printf ("\n"); + printf ("Dhrystone Benchmark, Version 2.1 (Language: C)\n"); + printf ("\n"); + if (Reg) + { + printf ("Program compiled with 'register' attribute\n"); + printf ("\n"); + } + else + { + printf ("Program compiled without 'register' attribute\n"); + printf ("\n"); + } + printf ("Please give the number of runs through the benchmark: "); + { + int n; + scanf ("%d", &n); + Number_Of_Runs = n; + } + printf ("\n"); + */ +#ifdef NRUNS + Number_Of_Runs = NRUNS; +#else + Number_Of_Runs = 2000000; +#endif + printf ("Execution starts, %d runs through Dhrystone\n", Number_Of_Runs); + + /***************/ + /* Start timer */ + /***************/ + +#ifdef TIMES + times (&time_info); + Begin_Time = (long) time_info.tms_utime; +#endif +#ifdef TIME + Begin_Time = time ( (long *) 0); +#endif +#ifdef MSC_CLOCK + Begin_Time = clock(); +#endif + + for (Run_Index = 1; Run_Index <= Number_Of_Runs; ++Run_Index) + { + + Proc_5(); + Proc_4(); + /* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */ + Int_1_Loc = 2; + Int_2_Loc = 3; + strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING"); + Enum_Loc = Ident_2; + Bool_Glob = ! Func_2 (Str_1_Loc, Str_2_Loc); + /* Bool_Glob == 1 */ + while (Int_1_Loc < Int_2_Loc) /* loop body executed once */ + { + Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc; + /* Int_3_Loc == 7 */ + Proc_7 (Int_1_Loc, Int_2_Loc, &Int_3_Loc); + /* Int_3_Loc == 7 */ + Int_1_Loc += 1; + } /* while */ + /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */ + Proc_8 (Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc); + /* Int_Glob == 5 */ + Proc_1 (Ptr_Glob); + for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index) + /* loop body executed twice */ + { + if (Enum_Loc == Func_1 (Ch_Index, 'C')) + /* then, not executed */ + { + Proc_6 (Ident_1, &Enum_Loc); + strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING"); + Int_2_Loc = Run_Index; + Int_Glob = Run_Index; + } + } + /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */ + Int_2_Loc = Int_2_Loc * Int_1_Loc; + Int_1_Loc = Int_2_Loc / Int_3_Loc; + Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc; + /* Int_1_Loc == 1, Int_2_Loc == 13, Int_3_Loc == 7 */ + Proc_2 (&Int_1_Loc); + /* Int_1_Loc == 5 */ + + } /* loop "for Run_Index" */ + + /**************/ + /* Stop timer */ + /**************/ + +#ifdef TIMES + times (&time_info); + End_Time = (long) time_info.tms_utime; +#endif +#ifdef TIME + End_Time = time ( (long *) 0); +#endif +#ifdef MSC_CLOCK + End_Time = clock(); +#endif + /* + printf ("Execution ends\n"); + printf ("\n"); + printf ("Final values of the variables used in the benchmark:\n"); + printf ("\n"); + printf ("Int_Glob: %d\n", Int_Glob); + printf (" should be: %d\n", 5); + printf ("Bool_Glob: %d\n", Bool_Glob); + printf (" should be: %d\n", 1); + printf ("Ch_1_Glob: %c\n", Ch_1_Glob); + printf (" should be: %c\n", 'A'); + printf ("Ch_2_Glob: %c\n", Ch_2_Glob); + printf (" should be: %c\n", 'B'); + printf ("Arr_1_Glob[8]: %d\n", Arr_1_Glob[8]); + printf (" should be: %d\n", 7); + printf ("Arr_2_Glob[8][7]: %d\n", Arr_2_Glob[8][7]); + printf (" should be: Number_Of_Runs + 10\n"); + printf ("Ptr_Glob->\n"); + printf (" Ptr_Comp: %d\n", (int) Ptr_Glob->Ptr_Comp); + printf (" should be: (implementation-dependent)\n"); + printf (" Discr: %d\n", Ptr_Glob->Discr); + printf (" should be: %d\n", 0); + printf (" Enum_Comp: %d\n", Ptr_Glob->variant.var_1.Enum_Comp); + printf (" should be: %d\n", 2); + printf (" Int_Comp: %d\n", Ptr_Glob->variant.var_1.Int_Comp); + printf (" should be: %d\n", 17); + printf (" Str_Comp: %s\n", Ptr_Glob->variant.var_1.Str_Comp); + printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n"); + printf ("Next_Ptr_Glob->\n"); + printf (" Ptr_Comp: %d\n", (int) Next_Ptr_Glob->Ptr_Comp); + printf (" should be: (implementation-dependent), same as above\n"); + printf (" Discr: %d\n", Next_Ptr_Glob->Discr); + printf (" should be: %d\n", 0); + printf (" Enum_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Enum_Comp); + printf (" should be: %d\n", 1); + printf (" Int_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Int_Comp); + printf (" should be: %d\n", 18); + printf (" Str_Comp: %s\n", + Next_Ptr_Glob->variant.var_1.Str_Comp); + printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n"); + printf ("Int_1_Loc: %d\n", Int_1_Loc); + printf (" should be: %d\n", 5); + printf ("Int_2_Loc: %d\n", Int_2_Loc); + printf (" should be: %d\n", 13); + printf ("Int_3_Loc: %d\n", Int_3_Loc); + printf (" should be: %d\n", 7); + printf ("Enum_Loc: %d\n", Enum_Loc); + printf (" should be: %d\n", 1); + printf ("Str_1_Loc: %s\n", Str_1_Loc); + printf (" should be: DHRYSTONE PROGRAM, 1'ST STRING\n"); + printf ("Str_2_Loc: %s\n", Str_2_Loc); + printf (" should be: DHRYSTONE PROGRAM, 2'ND STRING\n"); + printf ("\n"); + +*/ + User_Time = End_Time - Begin_Time; + + if (User_Time < Too_Small_Time) + { + printf ("Measured time too small to obtain meaningful results\n"); + printf ("Please increase number of runs\n"); + printf ("\n"); + } + else + { +#ifdef TIME + Microseconds = (float) User_Time * Mic_secs_Per_Second + / (float) Number_Of_Runs; + Dhrystones_Per_Second = (float) Number_Of_Runs / (float) User_Time; +#else + Microseconds = (float) User_Time * Mic_secs_Per_Second + / ((float) HZ * ((float) Number_Of_Runs)); + Dhrystones_Per_Second = ((float) HZ * (float) Number_Of_Runs) + / (float) User_Time; +#endif + printf ("Microseconds for one run through Dhrystone: "); + printf ("%6.1f \n", Microseconds); + printf ("Dhrystones per Second: "); + printf ("%6.1f \n", Dhrystones_Per_Second); + printf ("\n"); + printf ("This equals to %6.1f DMIPS\n", Dhrystones_Per_Second/1757); + } + +} + + +Proc_1 (Ptr_Val_Par) +/******************/ + +REG Rec_Pointer Ptr_Val_Par; + /* executed once */ +{ + REG Rec_Pointer Next_Record = Ptr_Val_Par->Ptr_Comp; + /* == Ptr_Glob_Next */ + /* Local variable, initialized with Ptr_Val_Par->Ptr_Comp, */ + /* corresponds to "rename" in Ada, "with" in Pascal */ + + structassign (*Ptr_Val_Par->Ptr_Comp, *Ptr_Glob); + Ptr_Val_Par->variant.var_1.Int_Comp = 5; + Next_Record->variant.var_1.Int_Comp + = Ptr_Val_Par->variant.var_1.Int_Comp; + Next_Record->Ptr_Comp = Ptr_Val_Par->Ptr_Comp; + Proc_3 (&Next_Record->Ptr_Comp); + /* Ptr_Val_Par->Ptr_Comp->Ptr_Comp + == Ptr_Glob->Ptr_Comp */ + if (Next_Record->Discr == Ident_1) + /* then, executed */ + { + Next_Record->variant.var_1.Int_Comp = 6; + Proc_6 (Ptr_Val_Par->variant.var_1.Enum_Comp, + &Next_Record->variant.var_1.Enum_Comp); + Next_Record->Ptr_Comp = Ptr_Glob->Ptr_Comp; + Proc_7 (Next_Record->variant.var_1.Int_Comp, 10, + &Next_Record->variant.var_1.Int_Comp); + } + else /* not executed */ + structassign (*Ptr_Val_Par, *Ptr_Val_Par->Ptr_Comp); +} /* Proc_1 */ + + +Proc_2 (Int_Par_Ref) +/******************/ + /* executed once */ + /* *Int_Par_Ref == 1, becomes 4 */ + +One_Fifty *Int_Par_Ref; +{ + One_Fifty Int_Loc; + Enumeration Enum_Loc; + + Int_Loc = *Int_Par_Ref + 10; + do /* executed once */ + if (Ch_1_Glob == 'A') + /* then, executed */ + { + Int_Loc -= 1; + *Int_Par_Ref = Int_Loc - Int_Glob; + Enum_Loc = Ident_1; + } /* if */ + while (Enum_Loc != Ident_1); /* true */ +} /* Proc_2 */ + + +Proc_3 (Ptr_Ref_Par) +/******************/ + /* executed once */ + /* Ptr_Ref_Par becomes Ptr_Glob */ + +Rec_Pointer *Ptr_Ref_Par; + +{ + if (Ptr_Glob != Null) + /* then, executed */ + *Ptr_Ref_Par = Ptr_Glob->Ptr_Comp; + Proc_7 (10, Int_Glob, &Ptr_Glob->variant.var_1.Int_Comp); +} /* Proc_3 */ + + +Proc_4 () /* without parameters */ +/*******/ + /* executed once */ +{ + Boolean Bool_Loc; + + Bool_Loc = Ch_1_Glob == 'A'; + Bool_Glob = Bool_Loc | Bool_Glob; + Ch_2_Glob = 'B'; +} /* Proc_4 */ + + +Proc_5 () /* without parameters */ +/*******/ + /* executed once */ +{ + Ch_1_Glob = 'A'; + Bool_Glob = false; +} /* Proc_5 */ + + + /* Procedure for the assignment of structures, */ + /* if the C compiler doesn't support this feature */ +#ifdef NOSTRUCTASSIGN +memcpy (d, s, l) +register char *d; +register char *s; +register int l; +{ + while (l--) *d++ = *s++; +} +#endif + + diff --git a/lib/CPUs/MIPS/bsp/examples/dhry_2.c b/lib/CPUs/MIPS/bsp/examples/dhry_2.c new file mode 100644 index 0000000..63a3d3e --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/dhry_2.c @@ -0,0 +1,192 @@ +/* + **************************************************************************** + * + * "DHRYSTONE" Benchmark Program + * ----------------------------- + * + * Version: C, Version 2.1 + * + * File: dhry_2.c (part 3 of 3) + * + * Date: May 25, 1988 + * + * Author: Reinhold P. Weicker + * + **************************************************************************** + */ + +#include "dhry.h" + +#ifndef REG +#define REG + /* REG becomes defined as empty */ + /* i.e. no register variables */ +#endif + +extern int Int_Glob; +extern char Ch_1_Glob; + + +Proc_6 (Enum_Val_Par, Enum_Ref_Par) +/*********************************/ + /* executed once */ + /* Enum_Val_Par == Ident_3, Enum_Ref_Par becomes Ident_2 */ + +Enumeration Enum_Val_Par; +Enumeration *Enum_Ref_Par; +{ + *Enum_Ref_Par = Enum_Val_Par; + if (! Func_3 (Enum_Val_Par)) + /* then, not executed */ + *Enum_Ref_Par = Ident_4; + switch (Enum_Val_Par) + { + case Ident_1: + *Enum_Ref_Par = Ident_1; + break; + case Ident_2: + if (Int_Glob > 100) + /* then */ + *Enum_Ref_Par = Ident_1; + else *Enum_Ref_Par = Ident_4; + break; + case Ident_3: /* executed */ + *Enum_Ref_Par = Ident_2; + break; + case Ident_4: break; + case Ident_5: + *Enum_Ref_Par = Ident_3; + break; + } /* switch */ +} /* Proc_6 */ + + +Proc_7 (Int_1_Par_Val, Int_2_Par_Val, Int_Par_Ref) +/**********************************************/ + /* executed three times */ + /* first call: Int_1_Par_Val == 2, Int_2_Par_Val == 3, */ + /* Int_Par_Ref becomes 7 */ + /* second call: Int_1_Par_Val == 10, Int_2_Par_Val == 5, */ + /* Int_Par_Ref becomes 17 */ + /* third call: Int_1_Par_Val == 6, Int_2_Par_Val == 10, */ + /* Int_Par_Ref becomes 18 */ +One_Fifty Int_1_Par_Val; +One_Fifty Int_2_Par_Val; +One_Fifty *Int_Par_Ref; +{ + One_Fifty Int_Loc; + + Int_Loc = Int_1_Par_Val + 2; + *Int_Par_Ref = Int_2_Par_Val + Int_Loc; +} /* Proc_7 */ + + +Proc_8 (Arr_1_Par_Ref, Arr_2_Par_Ref, Int_1_Par_Val, Int_2_Par_Val) +/*********************************************************************/ + /* executed once */ + /* Int_Par_Val_1 == 3 */ + /* Int_Par_Val_2 == 7 */ +Arr_1_Dim Arr_1_Par_Ref; +Arr_2_Dim Arr_2_Par_Ref; +int Int_1_Par_Val; +int Int_2_Par_Val; +{ + REG One_Fifty Int_Index; + REG One_Fifty Int_Loc; + + Int_Loc = Int_1_Par_Val + 5; + Arr_1_Par_Ref [Int_Loc] = Int_2_Par_Val; + Arr_1_Par_Ref [Int_Loc+1] = Arr_1_Par_Ref [Int_Loc]; + Arr_1_Par_Ref [Int_Loc+30] = Int_Loc; + for (Int_Index = Int_Loc; Int_Index <= Int_Loc+1; ++Int_Index) + Arr_2_Par_Ref [Int_Loc] [Int_Index] = Int_Loc; + Arr_2_Par_Ref [Int_Loc] [Int_Loc-1] += 1; + Arr_2_Par_Ref [Int_Loc+20] [Int_Loc] = Arr_1_Par_Ref [Int_Loc]; + Int_Glob = 5; +} /* Proc_8 */ + + +Enumeration Func_1 (Ch_1_Par_Val, Ch_2_Par_Val) +/*************************************************/ + /* executed three times */ + /* first call: Ch_1_Par_Val == 'H', Ch_2_Par_Val == 'R' */ + /* second call: Ch_1_Par_Val == 'A', Ch_2_Par_Val == 'C' */ + /* third call: Ch_1_Par_Val == 'B', Ch_2_Par_Val == 'C' */ + +Capital_Letter Ch_1_Par_Val; +Capital_Letter Ch_2_Par_Val; +{ + Capital_Letter Ch_1_Loc; + Capital_Letter Ch_2_Loc; + + Ch_1_Loc = Ch_1_Par_Val; + Ch_2_Loc = Ch_1_Loc; + if (Ch_2_Loc != Ch_2_Par_Val) + /* then, executed */ + return (Ident_1); + else /* not executed */ + { + Ch_1_Glob = Ch_1_Loc; + return (Ident_2); + } +} /* Func_1 */ + + +Boolean Func_2 (Str_1_Par_Ref, Str_2_Par_Ref) +/*************************************************/ + /* executed once */ + /* Str_1_Par_Ref == "DHRYSTONE PROGRAM, 1'ST STRING" */ + /* Str_2_Par_Ref == "DHRYSTONE PROGRAM, 2'ND STRING" */ + +Str_30 Str_1_Par_Ref; +Str_30 Str_2_Par_Ref; +{ + REG One_Thirty Int_Loc; + Capital_Letter Ch_Loc; + + Int_Loc = 2; + while (Int_Loc <= 2) /* loop body executed once */ + if (Func_1 (Str_1_Par_Ref[Int_Loc], + Str_2_Par_Ref[Int_Loc+1]) == Ident_1) + /* then, executed */ + { + Ch_Loc = 'A'; + Int_Loc += 1; + } /* if, while */ + if (Ch_Loc >= 'W' && Ch_Loc < 'Z') + /* then, not executed */ + Int_Loc = 7; + if (Ch_Loc == 'R') + /* then, not executed */ + return (true); + else /* executed */ + { + if (strcmp (Str_1_Par_Ref, Str_2_Par_Ref) > 0) + /* then, not executed */ + { + Int_Loc += 7; + Int_Glob = Int_Loc; + return (true); + } + else /* executed */ + return (false); + } /* if Ch_Loc */ +} /* Func_2 */ + + +Boolean Func_3 (Enum_Par_Val) +/***************************/ + /* executed once */ + /* Enum_Par_Val == Ident_3 */ +Enumeration Enum_Par_Val; +{ + Enumeration Enum_Loc; + + Enum_Loc = Enum_Par_Val; + if (Enum_Loc == Ident_3) + /* then, executed */ + return (true); + else /* not executed */ + return (false); +} /* Func_3 */ + diff --git a/lib/CPUs/MIPS/bsp/examples/dttl.c b/lib/CPUs/MIPS/bsp/examples/dttl.c new file mode 100644 index 0000000..8efffa2 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/dttl.c @@ -0,0 +1,261 @@ +/* dttl.c -- simulation of Cassini/Huygens symbol synchronizer loop + * + * Author: Lorenzo Simone's (matlab script) + * Modifications by: Jon Hamkins (conversion to C, support routines, + * memory requirement reductions) + * Last Revised: Wed Jan 31 10:47:52 PST 2001 + */ +#define M_PI 3.1415926535897932384626433832795 + +#include +#include +#include "random.h" + +/* global variables */ +int delay, + L; /* samples per symbol */ +double Pt, /* transition density */ + sigma; /* noise standard deviation */ +long seed=-123; + +/* This function simulates a large 1-dimensional array without requiring + * storage for the whole array. This is possible because the array is + * accessed in roughly increasing indices. Thus, we only need to + * store a few symbols worth of samples in the array, and we can reuse + * the array indices as time goes on. */ +int drint(double v) +{ + return (int)(v+0.5); +} + +double +rec(int idx) +{ + static int firsttime = 1, + max, /* maximum index containing data */ + mod, /* length of ring buffer */ + b; /* value of last transmitted bit */ + static double r[2000]; /* need several symbols worth of samples */ + int i,j,k; + + /* First time, store samples for random delay and first few symbols */ + if (firsttime==1) { + firsttime=0; + for (i=0; i0.5) ? 1 : -1; /* first random symbol */ + for (j=0; j<3; j++) { /* 3 binary symbols with transition Pt */ + b = (ran1(&seed)>Pt) ? b : -b; /* next symbol value */ + for (k=0; kmax) /* check if we need to create another sample */ + { + b = (ran1(&seed)>Pt) ? b : -b; /* next symbol value */ + /* generate samples for one symbol and store in ring buffer */ + for (i=1; i<=L; i++) r[(int)(fmod(max+i,mod))] = b+sigma*gaussian(&seed); + max += L; /* maximum index for which samples exist */ + } + /* return appropriate sample from ring buffer */ + return(r[(int)(fmod(idx,mod))]); +} + +main() +{ + double + detout, /* detector output */ + I, old_I, /* in-phase accumulations */ + Q, old_Q, /* quadrature accumulations */ + T, /* transition detection */ + theta, /* baseband NCO output (radians) */ + lambda, /* normalized timing error (symbols) */ + A, alfa, Ampl, Bl, Df, + DR, Es_No, Es_No_lin, Fc1, Fc2, Fvco, Fs, Kd, Kv, + lambda_ss_sim = 0., lambda_ss_th, No, P, P_No, + sigma_lambda_sim = 0., sigma_lambda_th, SNR_sim, SNR_th, tau, Tc1, Tc2, + time, Ts, x1, Y, bit_I, bit_Q, bit; + int i, j, k, N, offset, k1, k2, EOB; + FILE *p1, *p2, *p3, *p4, *p5; + + /* Data settings */ + Fc1 = 48000; /* sample rate at DTTL input (F1/2 = 8.215MHz/2) */ + Tc1 = 1./Fc1; + + DR = 4800; /* data rate (symb/sec) */ + + Fc2 = DR; /* sampling rate pre-detection */ + Tc2 = 1./Fc2; + + L = drint(Tc2/Tc1); /* samples per symbol in the arm filters */ + offset = drint(L/2.); + + Es_No = 600.; /* dB */ + P_No = Es_No+10.*log10(DR); /* data power-over-noise spectral density */ + /* ratio (dBHz) */ + + N = 2500; /* number of symbols to simulate */ + Pt=.5; /* Transition density */ + + Bl=0.01*DR; /* loop bandwidth (Hz) */ + Df=0.001*DR; /* frequency offset */ + Fvco=DR+Df; + + tau=ran1(&seed)-.5; /* set symbol timing offset, -.5 to .5 */ + delay=drint(2.*L+tau*L+1); /* channel delay */ + + P=1.; /* data power */ + Ampl=sqrt(P); + + No=10.*log10(P*Tc2)-Es_No; /* noise spectral density (dBW/Hz) */ + sigma=sqrt(pow(10.,0.1*No)/(2.*Tc1)); + printf("sigma=%f\n",sigma); + + /* DPLL settings */ + Fs=DR; /* loop sampling frequency (Hz) */ + Ts=1./Fs; /* loop sampling time (s) */ + + /* Loop gain */ + Kd=2.*Ampl*Pt; /* phase detector gain (quants/rad) */ + /* @ high Es/No */ + Kv=1.; /* VCO gain (rad/quants) */ + + /* Analog loop filter components */ + alfa=4.*Bl/(Kd*Kv); + + /* Digital loop filter components */ + A=alfa*Ts; + + /* Initial condition */ + theta = 0; + old_I=1; + old_Q=1; + x1=0; + Y=0; + + /* Plot data files */ +// p1 = fopen("plot1.dat","w"); /* theta */ +// p2 = fopen("plot2.dat","w"); /* lambda */ +// p3 = fopen("plot3.dat","w"); /* detout */ +// p4 = fopen("plot4.dat","w"); /* I-Data */ +// p5 = fopen("plot5.dat","w"); /* Q-Data */ + + k1 = drint(0.5*N); + k2 = N; + + printf("Data rate: %.0f symbols/sec\n",DR); + printf("Sample rate at DTTL input: %.0f samples/sec\n",Fc1); + printf("Samples per symbol: %d\n",L); + printf("Random delay set to: %f symbols (%d samples)\n",tau,delay); + printf("Transition density used in random bit generation: %f\n",Pt); + printf("Es/No: %f dB\n",Es_No); + printf("Loop bandwidth: %f Hz\n",Bl); + printf("Doppler: %f Hz\n",Df); + printf("Simulation length: %d symbols (%d samples)\n\n",N,N*L+delay); + + /* Simulation Loop */ + for (i=2; i<=N; i++) + { + /* loop over symbols */ + /* find start of in-phase integration */ + for (j=1; j < L; j++) + { + if (fmod(theta + 2*M_PI * Fvco*(j+1+(i-1)*(Fc1/DR))/Fc1, 2*M_PI) + < fmod(theta + 2*M_PI * Fvco*(j +(i-1)*(Fc1/DR))/Fc1, 2*M_PI)) + break; + /* one could replace loop above with a direct calculation such as: */ + /* j=ceil((1.-modulo(theta/(2*M_PI),1.))/(Fvco*Tc1))-1.; */ + /* j+1 is the first index in the block */ + EOB=j+(i-1)*L; /* End of Block */ + } + /* In-phase integrator */ + bit_I = 0.; + printf("Symbol # %d\n", i); + printf("I[%d:%d] :\n", EOB-L+1, EOB); + for (j=EOB-L+1; j<=EOB; j++) + { + bit = rec(j); + if (bit > 0) + printf("-"); + else + printf("_"); + + bit_I += bit; + } + printf("\n"); + I = bit_I; + + /* Mid-Phase integrator */ + bit_Q = 0.; + printf("Q[%d:%d] :\n", EOB-L+offset+1, EOB+offset); + for (j=EOB-L+offset+1; j<=EOB+offset; j++) + { + bit = rec(j); + if (bit > 0) + printf("-"); + else + printf("_"); + + bit_Q += bit; + } + printf("\n\n"); + Q = bit_Q; + + Q *= 2.*M_PI/(Tc2/Tc1); + + /* Transition Detector */ + I = (I > 0) ? 1. : -1.; /* hard limiter */ + T = 0.5*(I - old_I); + + /* Detector Output */ + detout = fmod(old_Q*T,2*M_PI); + + /* Save accumulations for next time through loop */ + old_I = I; + old_Q = Q; + if (fabs(detout)>M_PI) + detout = -detout+2*M_PI*((detout>0) ? 1. : -1.); + + /* NCO */ + Y += detout*A; /* Loop filter */ + theta=Kv*Y; /* phase */ +// lambda = theta/(2.*M_PI)+(i*Tc2*Df+tau); /* normalized error */ + lambda = theta/(2.*M_PI)+(i*(Fvco/DR -1) + tau); /* normalized error */ + + /* error mean and variance calculation */ + lambda_ss_sim += lambda; /* partial sum */ + sigma_lambda_sim += lambda*lambda; /* partial sum of squares */ + + /* store phase and normalized error to data files */ +// fprintf(p1,"%f %f\n",(double)i,theta); +// fprintf(p2,"%f %f\n",(double)i,lambda); +// fprintf(p3,"%f %f\n",(double)i,detout); +// fprintf(p4,"%f %f\n",(double)i,I); +// fprintf(p5,"%f %f\n",(double)i,Q); + } +// fclose(p1); +// fclose(p2); +// fclose(p3); +// fclose(p4); +// fclose(p5); + + /* Statistics Analysis */ + /* ------------------- */ + /* complete the mean and variance calculation */ + lambda_ss_sim /= N; + sigma_lambda_sim = sigma_lambda_sim/N - lambda_ss_sim*lambda_ss_sim; + Es_No_lin = pow(10.,0.1*Es_No); +// sigma_lambda_th = Bl*Tc2/(4.*Pt*Es_No_lin*pow(erf(sqrt(Es_No_lin)),2.)); + sigma_lambda_th = Bl*Tc2/(4.*Pt*Es_No_lin*Es_No_lin); + SNR_sim = -10*log10(sigma_lambda_sim); + SNR_th = -10*log10(sigma_lambda_th); + /* Steady-State error */ + lambda_ss_th=Df/(4.*Bl); + printf("Simulation: var: %f rad^2 loop SNR: %f dB ss error: %f%%\n", + sigma_lambda_sim, SNR_sim, 100.*lambda_ss_sim); + printf("Theory: var: %f rad^2 loop SNR: %f dB ss error: %f%%\n", + sigma_lambda_th, SNR_th, 100.*lambda_ss_th); +// system("gnuplot < plot1.gp"); +// system("gnuplot < plot2.gp"); + printf("Done.\n"); +} diff --git a/lib/CPUs/MIPS/bsp/examples/gunzip.c b/lib/CPUs/MIPS/bsp/examples/gunzip.c new file mode 100644 index 0000000..066c88e --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/gunzip.c @@ -0,0 +1,198 @@ +#include +#include +#include +#include +#include +#include + +#define CPU_FREQ_HZ 100000000 +#include "libsys.h" + +#include "crc32.h" +#include "inflate.h" + +char buffer[1024*1024]; +char * volatile pPtr_r; +char * volatile pPtr_w; +volatile int timeout_cnt; +volatile int file_len; + +void handler3(void) +{ + volatile UINT32 *pUART_stat = (UINT32*)SYS_UART0_STAT; + volatile UINT32 *pUART_data = (UINT32*)SYS_UART0_DATA; + + while(0x200 & *pUART_stat) + { +// sputs("w: "); print_word((int)pPtr_w); sputs("\n"); + if (pPtr_w == &buffer[sizeof(buffer)-1]) + pPtr_w = buffer; + *(pPtr_w++) = *pUART_data; + timeout_cnt = 100; + file_len++; + } + +} + +int READBYTE(z_stream *zs) { + if (zs->avail_in <= 0) + return -1; + + zs->avail_in --; + return *(zs->next_in ++); +} + +#define MAX_BUFOUT 16*1024*1024 +int main(int argc, char **argv) +{ + volatile UINT32 *pUART_stat = (UINT32*)SYS_UART0_STAT; + unsigned char outData[MAX_BUFOUT]; + FILE *infp; + int i, gpflags, tmp[4]; + unsigned long size, crc; + unsigned char *fileData; + unsigned long bytes, InflatedSize, InflatedCRC, speed_count; + z_stream zs; + time_t start_time, work_time; + + UART0_setbaud(460800); + + printf("Reading gzipped stream..\n"); + + pPtr_r = buffer; + pPtr_w = buffer; + *pUART_stat = (1 << 6); + interrupt_register(3, handler3); + interrupt_enable(3); + + file_len = 0; + timeout_cnt = 1000000; + while(timeout_cnt--) + { + sleep(1); + } + + printf("file_len: %d\n", file_len); + bytes = file_len; + fileData = pPtr_r; + + zs.next_in = fileData; + zs.avail_in = (unsigned int) bytes; + zs.next_out = outData; + zs.avail_out = MAX_BUFOUT; + + tmp[0] = READBYTE(&zs); + if (tmp[0] == -1) + { + // error reading from file + printf("error reading data from file\n"); + return 0; + } + tmp[1] = READBYTE(&zs); + + if (tmp[0] != 0x1f || tmp[1] != 0x8b) { +// fprintf(stderr, "Magic number mismatch 0x%02x%02x\n", +// tmp[0], tmp[1]); + return 20; + } + + tmp[0] = READBYTE(&zs); + if(tmp[0] != 8) { +// fprintf(stderr, "Unknown compression method: 0x%02x\n", tmp[0]); + return 20; + } + + gpflags = READBYTE(&zs); + if ((gpflags & ~0x1f)) { + printf("Unknown flags set!\n"); + } + + /* Skip file modification time (4 bytes) */ + READBYTE(&zs); + READBYTE(&zs); + READBYTE(&zs); + READBYTE(&zs); + /* Skip extra flags and operating system fields (2 bytes) */ + READBYTE(&zs); + READBYTE(&zs); + + if ((gpflags & 4)) { + /* Skip extra field */ + tmp[0] = READBYTE(&zs); + tmp[1] = READBYTE(&zs); + i = tmp[0] + 256*tmp[1]; + while (i--) + { + READBYTE(&zs); + } + } + if((gpflags & 8)) { + while((READBYTE(&zs))) { + } + } + if((gpflags & 16)) { + while((READBYTE(&zs))) { + } + } + if((gpflags & 2)) { + /* Skip CRC16 */ + READBYTE(&zs); + READBYTE(&zs); + } + + printf("Go\n"); + // normal test + start_time = clock(); + if (InflateData(&zs)) + { + printf("Problem during decompression!\n"); + return 0; + } + work_time = clock() - start_time; + + +/* + // speed test + fprintf(stdout, "SPEED TEST!\n"); + speed_count = 0; + while (time(NULL) - start_time < 20) + { + zs_speed.next_in = zs.next_in; + zs_speed.next_out = zs.next_out; + zs_speed.avail_in = zs.avail_in; + zs_speed.avail_out = zs.avail_out; + if (InflateData(&zs_speed)) + { + fprintf(stdout, "Problem during decompression!\n"); + return 0; + } + speed_count ++; + } + fprintf(stdout, "speed count %ld\n", speed_count); + zs.next_in = zs_speed.next_in; + zs.next_out = zs_speed.next_out; + zs.avail_in = zs_speed.avail_in; + zs.avail_out = zs_speed.avail_out; +*/ + + crc = READBYTE(&zs); + crc |= (READBYTE(&zs)<<8); + crc |= (READBYTE(&zs)<<16); + crc |= (READBYTE(&zs)<<24); + + size = READBYTE(&zs); + size |= (READBYTE(&zs)<<8); + size |= (READBYTE(&zs)<<16); + size |= (READBYTE(&zs)<<24); + + InflatedSize = MAX_BUFOUT - zs.avail_out; + InflatedCRC = MakeCRC32(outData, InflatedSize, 0); + +// write(1, outData, InflatedSize); + fprintf(stdout, "CRC: %08lx %08lx %s\n", crc, InflatedCRC, (crc != InflatedCRC)?"**error**":""); + fprintf(stdout, "Size: %08lx %08lx %s\n", size, InflatedSize, (size != InflatedSize)?"**error**":""); + fprintf(stdout, "Time for decompression was %.2f seconds\n", (float)work_time/1000); + fprintf(stdout, "Throughput is %d kByte/s\n", InflatedSize/work_time); + + return 0; +} diff --git a/lib/CPUs/MIPS/bsp/examples/hashtest.c b/lib/CPUs/MIPS/bsp/examples/hashtest.c new file mode 100644 index 0000000..b960966 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/hashtest.c @@ -0,0 +1,323 @@ +/********************************************************************\ + * + * FILE: hashtest.c + * + * CONTENTS: test file for sample C-implementation of + * RIPEMD-160 and RIPEMD128 + * * command line arguments: + * filename -- compute hash code of file read binary + * -sstring -- print string & hashcode + * -t -- perform time trial + * -x -- execute standard test suite, ASCII input + * * for linkage with rmd128.c: define RMDsize as 128 + * for linkage with rmd160.c: define RMDsize as 160 (default) + * TARGET: any computer with an ANSI C compiler + * + * AUTHOR: Antoon Bosselaers, ESAT-COSIC + * DATE: 18 April 1996 + * VERSION: 1.1 + * HISTORY: bug in RMDonemillion() corrected + * + * Copyright (c) Katholieke Universiteit Leuven + * 1996, All Rights Reserved + * + * Conditions for use of the RIPEMD-160 Software + * + * The RIPEMD-160 software is freely available for use under the terms and + * conditions described hereunder, which shall be deemed to be accepted by + * any user of the software and applicable on any use of the software: + * + * 1. K.U.Leuven Department of Electrical Engineering-ESAT/COSIC shall for + * all purposes be considered the owner of the RIPEMD-160 software and of + * all copyright, trade secret, patent or other intellectual property + * rights therein. + * 2. The RIPEMD-160 software is provided on an "as is" basis without + * warranty of any sort, express or implied. K.U.Leuven makes no + * representation that the use of the software will not infringe any + * patent or proprietary right of third parties. User will indemnify + * K.U.Leuven and hold K.U.Leuven harmless from any claims or liabilities + * which may arise as a result of its use of the software. In no + * circumstances K.U.Leuven R&D will be held liable for any deficiency, + * fault or other mishappening with regard to the use or performance of + * the software. + * 3. User agrees to give due credit to K.U.Leuven in scientific publications + * or communications in relation with the use of the RIPEMD-160 software + * as follows: RIPEMD-160 software written by Antoon Bosselaers, + * available at http://www.esat.kuleuven.be/~cosicart/ps/AB-9601/. + * +\********************************************************************/ +#ifndef RMDsize +#define RMDsize 160 +#endif + +#include +#include +#include +#include +#if RMDsize == 128 +#include "rmd128.h" +#elif RMDsize == 160 +#include "rmd160.h" +#endif + +#define TEST_BLOCK_SIZE 8000 +#define TEST_BLOCKS 1250 +#define TEST_BYTES ((long)TEST_BLOCK_SIZE * (long)TEST_BLOCKS) + +/********************************************************************/ + +byte *RMD(byte *message) +/* + * returns RMD(message) + * message should be a string terminated by '\0' + */ +{ + dword MDbuf[RMDsize/32]; /* contains (A, B, C, D(, E)) */ + static byte hashcode[RMDsize/8]; /* for final hash-value */ + dword X[16]; /* current 16-word chunk */ + unsigned int i; /* counter */ + dword length; /* length in bytes of message */ + dword nbytes; /* # of bytes not yet processed */ + + /* initialize */ + MDinit(MDbuf); + length = (dword)strlen((char *)message); + + /* process message in 16-word chunks */ + for (nbytes=length; nbytes > 63; nbytes-=64) { + for (i=0; i<16; i++) { + X[i] = BYTES_TO_DWORD(message); + message += 4; + } + compress(MDbuf, X); + } /* length mod 64 bytes left */ + + /* finish: */ + MDfinish(MDbuf, message, length, 0); + + for (i=0; i>2]; /* implicit cast to byte */ + hashcode[i+1] = (MDbuf[i>>2] >> 8); /* extracts the 8 least */ + hashcode[i+2] = (MDbuf[i>>2] >> 16); /* significant bits. */ + hashcode[i+3] = (MDbuf[i>>2] >> 24); + } + + return (byte *)hashcode; +} + +/********************************************************************/ + +byte *RMDbinary(char *fname) +/* + * returns RMD(message in file fname) + * fname is read as binary data. + */ +{ + FILE *mf; /* pointer to file */ + byte data[1024]; /* contains current mess. block */ + dword nbytes; /* length of this block */ + dword MDbuf[RMDsize/32]; /* contains (A, B, C, D(, E)) */ + static byte hashcode[RMDsize/8]; /* for final hash-value */ + dword X[16]; /* current 16-word chunk */ + unsigned int i, j; /* counters */ + dword length[2]; /* length in bytes of message */ + dword offset; /* # of unprocessed bytes at */ + /* call of MDfinish */ + + /* initialize */ + if ((mf = fopen(fname, "rb")) == NULL) { + fprintf(stderr, "\nRMDbinary: cannot open file \"%s\".\n", + fname); + exit(1); + } + MDinit(MDbuf); + length[0] = 0; + length[1] = 0; + + while ((nbytes = fread(data, 1, 1024, mf)) != 0) { + /* process all complete blocks */ + for (i=0; i<(nbytes>>6); i++) { + for (j=0; j<16; j++) + X[j] = BYTES_TO_DWORD(data+64*i+4*j); + compress(MDbuf, X); + } + /* update length[] */ + if (length[0] + nbytes < length[0]) + length[1]++; /* overflow to msb of length */ + length[0] += nbytes; + } + + /* finish: */ + offset = length[0] & 0x3C0; /* extract bytes 6 to 10 inclusive */ + MDfinish(MDbuf, data+offset, length[0], length[1]); + + for (i=0; i>2]; + hashcode[i+1] = (MDbuf[i>>2] >> 8); + hashcode[i+2] = (MDbuf[i>>2] >> 16); + hashcode[i+3] = (MDbuf[i>>2] >> 24); + } + + fclose(mf); + + return (byte *)hashcode; +} + +/********************************************************************/ + +void speedtest(void) +/* + * A time trial routine, to measure the speed of ripemd. + * Measures processor time required to process TEST_BLOCKS times + * a message of TEST_BLOCK_SIZE characters. + */ +{ + clock_t t0, t1; + byte *data; + byte hashcode[RMDsize/8]; + dword X[16]; + dword MDbuf[RMDsize/32]; + unsigned int i, j, k; + + srand(time(NULL)); + + /* allocate and initialize test data */ + if ((data = (byte*)malloc(TEST_BLOCK_SIZE)) == NULL) { + fprintf(stderr, "speedtest: allocation error\n"); + exit(1); + } + for (i=0; i> 7); + + /* start timer */ + printf("\n\nRIPEMD-%u time trial. Processing %ld characters...\n", + RMDsize, TEST_BYTES); + t0 = clock(); + + /* process data */ + MDinit(MDbuf); + for (i=0; i %3.2f Mbit/s\n\n", 8*(double)CLOCKS_PER_SEC*TEST_BYTES/((double)t1-t0)/(1024*1024)); + + for (i=0; i>2]; + hashcode[i+1] = (MDbuf[i>>2] >> 8); + hashcode[i+2] = (MDbuf[i>>2] >> 16); + hashcode[i+3] = (MDbuf[i>>2] >> 24); + } + printf("\nhashcode: "); + for (i=0; i0; i--) + compress(MDbuf, X); + MDfinish(MDbuf, NULL, 1000000UL, 0); + for (i=0; i>2]; + hashcode[i+1] = (MDbuf[i>>2] >> 8); + hashcode[i+2] = (MDbuf[i>>2] >> 16); + hashcode[i+3] = (MDbuf[i>>2] >> 24); + } + printf("\n* message: 1 million times \"a\"\n hashcode: "); + for (i=0; i +#define A 0.5 +#define B 0.55 + +_Sat long _Fract sat_add3 (_Sat long _Fract a, _Sat long _Fract b) +{ + return a + b; +} + +long _Fract mul3 (long _Fract a, long _Fract b) +{ + return a * b; +} + +int main() +{ + printf("hello %X + %X = %X\n", (_Sat long _Fract)A, (_Sat long _Fract)B, sat_add3(A, B)); + printf("hello %X * %X = %X\n", (_Sat long _Fract)A, (_Sat long _Fract)B, mul3(A, B)); +} diff --git a/lib/CPUs/MIPS/bsp/examples/hpi.c b/lib/CPUs/MIPS/bsp/examples/hpi.c new file mode 100644 index 0000000..3a21263 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/hpi.c @@ -0,0 +1,949 @@ +#include +#include +#include +#include +#include "libsys.h" +#include "hpi.h" + +static volatile UINT32 _g_int_active; +static volatile UINT32 _g_mbx_return; +static volatile UINT32 _g_mbx_in_flag; + +// --------------------------------------------------------- +// Globals +// --------------------------------------------------------- +typedef struct _susb_t +{ + fp_t fptr_ept[USB_MAX_NUM_EPT]; + void *aptr_ept[USB_MAX_NUM_EPT]; + + fp_t fptr_rst; + void *aptr_rst; + + fp_t fptr_sof; + void *aptr_sof; + + fp_t fptr_cfg; + void *aptr_cfg; + + fp_t fptr_sus; + void *aptr_sus; + + fp_t fptr_id; + void *aptr_id; + + fp_t fptr_vbus; + void *aptr_vbus; + +} usb_t; + +static usb_t _g_usb[USB_MAX_NUM_PORTS]; +//static usb_irp_t *_g_usb_irp_ptr[USB_MAX_NUM_PORTS][USB_MAX_NUM_EPT]; + +// --------------------------------------------------------- +// HPI ISR +// --------------------------------------------------------- +void cy67k3_isr(void) +{ + INT32 i; + UINT16 sie_msg, hpi_status; + UINT32 port, siemsg_handled, int_handled; + _g_int_active = 1; +// sputs("--------------------------------------------------------\n"); +// sputs("USB-Interrupt(4)\n"); +// sputs("HPI Status : "); + hpi_status = cy67k3_read_HPI_STATUS(); +// print_word(hpi_status); +// sputs("\n"); + +// sputs("MAILBOX (REG): "); + +// cy67k3_write(HPI_ADDRESS, HPI_REG_MAILBOX); +// print_word(cy67k3_read_HPI_DATA()); +// sputs("\n"); + + int_handled = 0; + if (hpi_status & HPI_STATUS_MBX_IN) + { + int_handled = 1; +// sputs("MAILBOX (HPI): "); + _g_mbx_return = cy67k3_read_HPI_MAILBOX(); + _g_mbx_in_flag = 1; +// print_word(_g_mbx_return); +// sputs("\n"); + } + + if (hpi_status & HPI_STATUS_RESET1) + { + int_handled = 1; + hpi_read_reg(SUSB1_REG_STATUS); + hpi_comm_exec_int(SUSB_INIT_INT, 2, R1, 0, R2, 1); +// sputs("RESET 1\n"); + } + + if (hpi_status & HPI_STATUS_RESET2) + { + int_handled = 1; + hpi_read_reg(SUSB2_REG_STATUS); + hpi_comm_exec_int(SUSB_INIT_INT, 2, R1, 0, R2, 2); +// sputs("RESET 2\n"); + } + + if (hpi_status & HPI_STATUS_DONE1) + { + int_handled = 1; +// sputs("DONE 1\n"); + } + + if (hpi_status & HPI_STATUS_DONE2) + { + int_handled = 1; +// sputs("DONE 2\n"); + } + + if (hpi_status & HPI_STATUS_SOFEOP1) + { + int_handled = 1; + hpi_read_reg(SUSB1_REG_STATUS); +// sputs("SOF/EOP 1\n"); + } + + if (hpi_status & HPI_STATUS_SOFEOP2) + { + int_handled = 1; + hpi_read_reg(SUSB2_REG_STATUS); +// sputs("SOF/EOP 2\n"); + } + + port = 0; + siemsg_handled = 0; + if (hpi_status & HPI_STATUS_SIEMSG1) + { + int_handled = 1; + sie_msg = hpi_read_reg(HPI_REG_SIE1MSG); + + // Reset message register + hpi_write_reg(HPI_REG_SIE1MSG, 0x0000); + + if (sie_msg & SUSB_RST_MSG) + { + siemsg_handled = 1; + if (_g_usb[port].fptr_rst) + (_g_usb[port].fptr_rst)(_g_usb[port].aptr_rst); + } + + if (sie_msg & SUSB_SOF_MSG) + { + siemsg_handled = 1; + if (_g_usb[port].fptr_sof) + (_g_usb[port].fptr_sof)(_g_usb[port].aptr_sof); + } + + if (sie_msg & SUSB_CFG_MSG) + { + siemsg_handled = 1; + if (_g_usb[port].fptr_cfg) + (_g_usb[port].fptr_cfg)(_g_usb[port].aptr_cfg); + } + + if (sie_msg & SUSB_SUS_MSG) + { + siemsg_handled = 1; + if (_g_usb[port].fptr_sus) + (_g_usb[port].fptr_sus)(_g_usb[port].aptr_sus); + } + + if (sie_msg & SUSB_ID_MSG) + { + siemsg_handled = 1; + if (_g_usb[port].fptr_id) + (_g_usb[port].fptr_id)(_g_usb[port].aptr_id); + } + + if (sie_msg & SUSB_VBUS_MSG) + { + siemsg_handled = 1; + if (_g_usb[port].fptr_vbus) + (_g_usb[port].fptr_vbus)(_g_usb[port].aptr_vbus); + } + + for (i=0; i < 8; i++) + { + if (sie_msg & (SUSB_EP0_MSG << i)) + { + siemsg_handled = 1; + if (_g_usb[port].fptr_ept[i]) + (_g_usb[port].fptr_ept[i])(_g_usb[port].aptr_ept[i]); + } + } + if (!siemsg_handled) + { + sputs("Unhandled SIE1 message "); + print_word(sie_msg); + sputs("!\n"); + } + + } + port = 1; + siemsg_handled = 0; + if (hpi_status & HPI_STATUS_SIEMSG2) + { + int_handled = 1; + sie_msg = hpi_read_reg(HPI_REG_SIE2MSG); + + // Reset message register + hpi_write_reg(HPI_REG_SIE2MSG, 0x0000); + + if (sie_msg & SUSB_RST_MSG) + { + siemsg_handled = 1; + if (_g_usb[port].fptr_rst) + (_g_usb[port].fptr_rst)(_g_usb[port].aptr_rst); + } + + if (sie_msg & SUSB_SOF_MSG) + { + siemsg_handled = 1; + if (_g_usb[port].fptr_sof) + (_g_usb[port].fptr_sof)(_g_usb[port].aptr_sof); + } + + if (sie_msg & SUSB_CFG_MSG) + { + siemsg_handled = 1; + if (_g_usb[port].fptr_cfg) + (_g_usb[port].fptr_cfg)(_g_usb[port].aptr_cfg); + } + + if (sie_msg & SUSB_SUS_MSG) + { + siemsg_handled = 1; + if (_g_usb[port].fptr_sus) + (_g_usb[port].fptr_sus)(_g_usb[port].aptr_sus); + } + + if (sie_msg & SUSB_ID_MSG) + { + siemsg_handled = 1; + if (_g_usb[port].fptr_id) + (_g_usb[port].fptr_id)(_g_usb[port].aptr_id); + } + + if (sie_msg & SUSB_VBUS_MSG) + { + siemsg_handled = 1; + if (_g_usb[port].fptr_vbus) + (_g_usb[port].fptr_vbus)(_g_usb[port].aptr_vbus); + } + + for (i=0; i < 8; i++) + { + if (sie_msg & (SUSB_EP0_MSG << i)) + { + siemsg_handled = 1; + if (_g_usb[port].fptr_ept[i]) + (_g_usb[port].fptr_ept[i])(_g_usb[port].aptr_ept[i]); + } + } + if (!siemsg_handled) + { + sputs("Unhandled SIE2 message "); + print_word(sie_msg); + sputs("!\n"); + } + + } + if (!int_handled) + { + sputs("Unhandled interrupt (status = "); + print_word(hpi_status); + sputs(")!\n"); + } + +// sputs("--------------------------------------------------------\n"); + _g_int_active = 0; +} + +// --------------------------------------------------------- +// CY7C67300 low-level routines +// --------------------------------------------------------- +void cy67k3_reset(void) +{ + int i; + volatile UINT32 *pHpi = (UINT32*)SYS_USB_CTRL; + + *pHpi = 3; + for (i=0; i <160; i++) + { + __asm __volatile + ( + ".set noreorder\n" + "nop\n" + "nop\n" + "nop\n" + "nop\n" + ".set reorder\n" + ); + } + + *pHpi = 2; + +} + +UINT16 cy67k3_read_HPI_DATA(void) +{ + volatile UINT32 *pHpi = (UINT32*)SYS_USB_DATA; + + return (UINT16)*pHpi; +} + +UINT16 cy67k3_read_HPI_MAILBOX(void) +{ + volatile UINT32 *pHpi = (UINT32*)SYS_USB_MBX; + + return (UINT16)*pHpi; +} + +UINT16 cy67k3_read_HPI_ADDRESS(void) +{ + volatile UINT32 *pHpi = (UINT32*)SYS_USB_ADDR; + + return (UINT16)*pHpi; +} + +UINT16 cy67k3_read_HPI_STATUS(void) +{ + volatile UINT32 *pHpi = (UINT32*)SYS_USB_STATUS; + + return (UINT16)*pHpi; +} + +void cy67k3_write_HPI_DATA(UINT16 data) +{ + volatile UINT32 *pHpi = (UINT32*)SYS_USB_DATA; + + *pHpi = (UINT32)data; +} + +void cy67k3_write_HPI_MAILBOX(UINT16 data) +{ + volatile UINT32 *pHpi = (UINT32*)SYS_USB_MBX; + + *pHpi = (UINT32)data; +} + +void cy67k3_write_HPI_ADDRESS(UINT16 data) +{ + volatile UINT32 *pHpi = (UINT32*)SYS_USB_ADDR; + + *pHpi = (UINT32)data; +} + +void cy67k3_write_HPI_STATUS(UINT16 data) +{ + volatile UINT32 *pHpi = (UINT32*)SYS_USB_STATUS; + + *pHpi = (UINT32)data; +} + +// --------------------------------------------------------- +// HPI API +// --------------------------------------------------------- +UINT32 hpi_init(void) +{ + volatile UINT32 *pHpi = (UINT32*)SYS_USB_CTRL; + int i; + UINT16 reg; + + // ToDo: Enable HPI interrupt + _g_int_active = 0; + + hpi_write_reg(HPI_REG_SIE1MSG, 0x0000); + hpi_write_reg(HPI_REG_SIE2MSG, 0x0000); + hpi_write_reg(SUSB1_REG_STATUS, 0xFFFF); + hpi_write_reg(SUSB2_REG_STATUS, 0xFFFF); + + // Init 1 + for(i=0; i < USB_MAX_NUM_EPT; i++) + { + hpi_write_reg(SUSB1_REG_EP_ADDR0 + 16*i, 0); + hpi_write_reg(SUSB1_REG_EP_CNTRES0 + 16*i, 0); + hpi_write_reg(SUSB1_REG_EP_COUNT0 + 16*i, 0); + hpi_write_reg(SUSB1_REG_EP_CTRL0 + 16*i, 0); + hpi_write_reg(SUSB1_REG_EP_STATUS0 + 16*i, 0); + } + // Init 2 + for(i=0; i < USB_MAX_NUM_EPT; i++) + { + hpi_write_reg(SUSB2_REG_EP_ADDR0 + 16*i, 0); + hpi_write_reg(SUSB2_REG_EP_CNTRES0 + 16*i, 0); + hpi_write_reg(SUSB2_REG_EP_COUNT0 + 16*i, 0); + hpi_write_reg(SUSB2_REG_EP_CTRL0 + 16*i, 0); + hpi_write_reg(SUSB2_REG_EP_STATUS0 + 16*i, 0); + } + + hpi_write_reg(HPI_REG_INTROUTE, 0x0000); + reg = hpi_read_reg(HPI_REG_INTROUTE); +// hpi_write_reg(HPI_REG_INTROUTE, reg | 0x0202); // Route reset {1,2} to HPI only +// hpi_write_reg(HPI_REG_INTROUTE, reg | 0x2800); // Route SOF/EOP {1,2} to HPI only +// hpi_write_reg(HPI_REG_INTROUTE, reg | 0x1400); // Route SOF/EOP {1,2} to CY16 only + hpi_write_reg(HPI_REG_INTROUTE, reg | 0x3C00); // Route SOF/EOP {1,2} to HPI and CY16 + + + interrupt_register(4, cy67k3_isr); + interrupt_enable(4); + *pHpi = 0x02; + + return HPI_NOERROR; +} + +void hpi_mbx_write(UINT16 msgcode) +{ + _g_mbx_in_flag = 0; + cy67k3_write_HPI_MAILBOX(msgcode); +} + +UINT32 hpi_mbx_read(void) +{ + UINT32 err; + UINT16 cy_return; + + if (_g_int_active) + { + while (!(cy67k3_read_HPI_STATUS() & HPI_STATUS_MBX_IN)); + cy_return = cy67k3_read_HPI_MAILBOX(); + } + else + { + while(!_g_mbx_in_flag); + cy_return = _g_mbx_return; + } + + switch (cy_return) + { + case COMM_ACK: + err = cy_return; + break; + + case COMM_NAK: + case COMM_ASYNC: + err = HPI_ERR_PREFIX_MBX | cy_return; + break; + + default: + err = HPI_ERR_PREFIX_MBX | cy_return; + break; + } + return err; +} + +UINT32 hpi_check_addr(UINT16 addr) +{ + if ((addr >= 0x0000) && (addr < 0x4000)) + return 0; + + if ((addr >= 0xC080) && (addr < 0xC0BC)) + return 0; + + if (addr >= 0xE000) + return 0; + + sputs("Invalid address for HPI direct access! Use LCP-command instead!\n"); + return HPI_ERR_INVPARAM; +} + +UINT32 hpi_read_reg(UINT16 addr) +{ + UINT32 result; + + result = hpi_check_addr(addr); + if (IS_ERROR(result)) + return result; + + cy67k3_write_HPI_ADDRESS(addr); + return cy67k3_read_HPI_DATA(); +} + +UINT32 hpi_write_reg(UINT16 addr, UINT16 data) +{ + UINT32 result; + + result = hpi_check_addr(addr); + if (IS_ERROR(result)) + return result; + + cy67k3_write_HPI_ADDRESS(addr); + cy67k3_write_HPI_DATA(data); +} + +UINT32 hpi_write_ram(UINT16 addr, UINT16 *pData, UINT32 len) +{ + int i, num_words; + + if (addr > 0x3FFE) + return HPI_ERR_INVPARAM; + + if (addr & 1) // Not 16bit aligned? + return HPI_ERR_INVPARAM; + + cy67k3_write_HPI_ADDRESS(addr); + + num_words = len/2; + if (len % 2) + num_words++; + + for (i=0; i < num_words; i++) + cy67k3_write_HPI_DATA(pData[i]); + + return len; +} + +UINT32 hpi_read_ram(UINT16 addr, UINT16 *pData, UINT32 len) +{ + int i, num_words; + + if (addr > 0x3FFE) + return HPI_ERR_INVPARAM; + + if (addr & 1) // Not 16bit aligned? + return HPI_ERR_INVPARAM; + + cy67k3_write_HPI_ADDRESS(addr); + + num_words = len/2; + if (len % 2) + num_words++; + + for (i=0; i < num_words; i++) + pData[i] = cy67k3_read_HPI_DATA(); + + return len; +} + +UINT32 hpi_comm_reset(void) +{ + hpi_mbx_write(COMM_RESET); + + return hpi_mbx_read(); +} + +UINT32 hpi_comm_jump2code(UINT16 addr) +{ + cy67k3_write_HPI_ADDRESS(addr); + hpi_mbx_write(COMM_JUMP2CODE); + + return hpi_mbx_read(); +} + +UINT32 hpi_comm_callcode(UINT16 addr) +{ + hpi_write_reg(COMM_CODE_ADDR, addr); + + hpi_mbx_write(COMM_CALL_CODE); + + return hpi_mbx_read(); +} + +UINT32 hpi_comm_write_ctrl_reg(UINT16 addr, UINT16 data, UINT16 logic) +{ + + hpi_write_reg(COMM_CTRL_REG_ADDR, addr); + hpi_write_reg(COMM_CTRL_REG_DATA, data); + hpi_write_reg(COMM_CTRL_REG_LOGIC, logic); + + hpi_mbx_write(COMM_WRITE_CTRL_REG); + + return hpi_mbx_read(); +} + +UINT32 hpi_comm_read_ctrl_reg(UINT16 addr) +{ + UINT32 result; + + hpi_write_reg(COMM_CTRL_REG_ADDR, addr); + + hpi_mbx_write(COMM_READ_CTRL_REG); + + result = hpi_mbx_read(); + if (IS_ERROR(result)) + return result; + + cy67k3_write_HPI_ADDRESS(COMM_CTRL_REG_DATA); + return (UINT32)cy67k3_read_HPI_DATA(); + +} + +UINT32 hpi_comm_write_xmem(UINT16 addr, UINT8 *pData, UINT16 len) +{ + return HPI_ERR_NOTIMPL; + +} + +UINT32 hpi_comm_read_xmem(UINT16 addr, UINT8 *pData, UINT16 len) +{ + return HPI_ERR_NOTIMPL; + +} + +typedef struct _sreg_param_t +{ + UINT32 id; + UINT16 val; + +} reg_param_t; + +UINT32 hpi_comm_exec_int(UINT16 intnum, UINT32 nargs, ...) +{ + int i; + UINT32 result; + va_list args; + reg_param_t reg_param[MAX_NUM_REGS]; + + va_start(args, nargs); + + if (nargs > MAX_NUM_REGS) + { + fprintf(stderr, "hpi_comm_exec_int(): Number (%d), of arguments exceeds %d!\n", nargs, MAX_NUM_REGS); + return HPI_ERR_INVPARAM; + } + + for (i=0; i < nargs; i++) + { + reg_param[i].id = va_arg(args, UINT32); + if (reg_param[i].id > MAX_NUM_REGS) + { + fprintf(stderr, "hpi_comm_exec_int(): Invalid register R%d!\n", reg_param[i].id); + return HPI_ERR_INVPARAM; + } + + reg_param[i].val = (UINT16)va_arg(args, UINT32); + } + va_end(args); + + hpi_write_reg(COMM_INT_NUM, intnum); + + for (i=0; i < nargs; i++) + { + hpi_write_reg(COMM_R0 + 2*reg_param[i].id, reg_param[i].val); + } + + hpi_mbx_write(COMM_EXEC_INT); + + result = hpi_mbx_read(); + if (IS_ERROR(result)) + return result; + + return (UINT32)hpi_read_reg(COMM_R0); +} + +UINT32 usb_init(void) +{ + INT32 i; + + for (i=0; i < USB_MAX_NUM_PORTS; i++) + { + memset(&_g_usb[i], 0, sizeof(usb_t)); + } + return 0; +} + +UINT32 usb_callback_register(UINT32 port, UINT32 type, fp_t pFunc, void *pArg) +{ + UINT32 result; + if (port >= USB_MAX_NUM_PORTS) + return -1; + + result = 0; + switch (type) + { + case SUSB_EP0_MSG: + _g_usb[port].fptr_ept[0] = pFunc; + _g_usb[port].aptr_ept[0] = pArg; + break; + + case SUSB_EP1_MSG: + _g_usb[port].fptr_ept[1] = pFunc; + _g_usb[port].aptr_ept[1] = pArg; + break; + + case SUSB_EP2_MSG: + _g_usb[port].fptr_ept[2] = pFunc; + _g_usb[port].aptr_ept[2] = pArg; + break; + + case SUSB_EP3_MSG: + _g_usb[port].fptr_ept[3] = pFunc; + _g_usb[port].aptr_ept[3] = pArg; + break; + + case SUSB_EP4_MSG: + _g_usb[port].fptr_ept[4] = pFunc; + _g_usb[port].aptr_ept[4] = pArg; + break; + + case SUSB_EP5_MSG: + _g_usb[port].fptr_ept[5] = pFunc; + _g_usb[port].aptr_ept[5] = pArg; + break; + + case SUSB_EP6_MSG: + _g_usb[port].fptr_ept[6] = pFunc; + _g_usb[port].aptr_ept[6] = pArg; + break; + + case SUSB_EP7_MSG: + _g_usb[port].fptr_ept[7] = pFunc; + _g_usb[port].aptr_ept[7] = pArg; + break; + + case SUSB_RST_MSG: + _g_usb[port].fptr_rst = pFunc; + _g_usb[port].aptr_rst = pArg; + break; + + case SUSB_SOF_MSG: + _g_usb[port].fptr_sof = pFunc; + _g_usb[port].aptr_sof = pArg; + break; + + case SUSB_CFG_MSG: + _g_usb[port].fptr_cfg = pFunc; + _g_usb[port].aptr_cfg = pArg; + break; + + case SUSB_SUS_MSG: + _g_usb[port].fptr_sus = pFunc; + _g_usb[port].aptr_sus = pArg; + break; + + case SUSB_ID_MSG: + _g_usb[port].fptr_id = pFunc; + _g_usb[port].aptr_id = pArg; + break; + + case SUSB_VBUS_MSG: + _g_usb[port].fptr_vbus = pFunc; + _g_usb[port].aptr_vbus = pArg; + break; + + default: + result = -1; + break; + } + + return result; +} + +UINT32 usb_irp_register(usb_irp_t *pIRP, UINT32 port, UINT32 ept, UINT32 size, UINT32 is_out) +{ + + if (!pIRP) + return -1; + + if (port >= USB_MAX_NUM_PORTS) + return -1; + + if (ept >= USB_MAX_NUM_EPT) + return -1; + + if (size >= USB_MAX_IMG_SIZE) + return -1; + + memset(pIRP, 0, sizeof(usb_irp_t)); + pIRP->is_out = is_out; + pIRP->is_in = !is_out; + pIRP->tsize = size; + pIRP->port = port; + pIRP->ept = ept; + pIRP->cy_irp_addr = USB_IRP_BASE + port*USB_MAX_NUM_EPT*sizeof(cy_req_t) + ept*sizeof(cy_req_t); + pIRP->cy_req.next = 0; + pIRP->cy_req.addr = USB_IMG_BASE + port*USB_MAX_NUM_EPT*USB_MAX_IMG_SIZE + ept*USB_MAX_IMG_SIZE; + pIRP->cy_req.size = size; + pIRP->cy_req.callback = 0; + fifo_alloc(&pIRP->fifo, 8*USB_MAX_IMG_SIZE); + + return 0; +} + +UINT32 usb_irp_enqueue(usb_irp_t *pIRP) +{ + UINT32 result; + + if (!pIRP) + { +// sputs ("usb_irp_enqueue(): Invalid IRP!\n"); + return -1; + } + +// printf("cy_addr: %4.4X, Next: %4.4X, Addr: %4.4X, Size: %4.4X, CB: %4.4X\n", pIRP->cy_irp_addr, pIRP->cy_req.next, pIRP->cy_req.addr, pIRP->cy_req.size, pIRP->cy_req.callback); + + if (pIRP->is_out) + { + hpi_write_ram(pIRP->cy_irp_addr, (UINT16*)&pIRP->cy_req, sizeof(cy_req_t)); + if (pIRP->port == 0) + result = hpi_comm_exec_int(SUSB1_RECEIVE_INT, 2, R1, pIRP->ept, R8, pIRP->cy_irp_addr); + + if (pIRP->port == 1) + result = hpi_comm_exec_int(SUSB2_RECEIVE_INT, 2, R1, pIRP->ept, R8, pIRP->cy_irp_addr); + } + if (pIRP->is_in) + { + pIRP->tx_in_progress = 1; + hpi_write_ram(pIRP->cy_irp_addr, (UINT16*)&pIRP->cy_req, sizeof(cy_req_t)); + if (pIRP->port == 0) + result = hpi_comm_exec_int(SUSB1_SEND_INT, 2, R1, pIRP->ept, R8, pIRP->cy_irp_addr); + + if (pIRP->port == 1) + result = hpi_comm_exec_int(SUSB2_SEND_INT, 2, R1, pIRP->ept, R8, pIRP->cy_irp_addr); + } + +// if (result) +// printf ("usb_irp_enqueue(): Result = %8.8X\n", result); + + return result; + +} + +UINT32 fifo_alloc(fifo_t *pObj, UINT32 size) +{ + pObj->pBuf = (UINT8*)malloc(size); + if (!pObj->pBuf) + { +// printf ("fifo_alloc(): Error allocating memory!\n"); + return -1; + } +// printf ("fifo_alloc(): pBuf at %8.8X\n", (UINT32)pObj->pBuf); + pObj->size = size; + pObj->pPtr_wr = pObj->pBuf; + pObj->pPtr_rd = pObj->pBuf; + + return 0; +} + +UINT32 fifo_free(fifo_t *pObj) +{ + if (pObj->pBuf) + free(pObj->pBuf); + + return 0; +} + +UINT32 fifo_flush(fifo_t *pObj) +{ + pObj->pPtr_wr = pObj->pBuf; + pObj->pPtr_rd = pObj->pBuf; + + return 0; +} + +UINT32 fifo_is_empty(fifo_t *pObj) +{ + return (pObj->pPtr_wr == pObj->pPtr_rd); +} + +UINT32 fifo_is_full(fifo_t *pObj) +{ + UINT8 *pNext, *pEnd; + + pEnd = pObj->pBuf + pObj->size; + pNext = pObj->pPtr_wr + 1; + if (pNext == pEnd) + pNext = pObj->pBuf; + + return (pNext == pObj->pPtr_rd); +} + +UINT32 fifo_read(fifo_t *pObj, UINT8 *pData, UINT32 size, UINT32 timeout, UINT32 do_block) +{ + UINT32 i; + UINT32 wait_4ever, timeout_cnt, cnt; + UINT8 *pEnd; + + pEnd = pObj->pBuf + pObj->size; + wait_4ever = (timeout == 0); + + cnt = 0; + while(size) + { + timeout_cnt = timeout; + + while(fifo_is_empty(pObj)) + { + if (!do_block) + return cnt; + + if (!wait_4ever) + { + if (timeout_cnt) + { + timeout_cnt--; + sleep(1); + } + else + { + return cnt; + } + } + } + + if (pData) + pData[cnt] = *(pObj->pPtr_rd); + + cnt++; + pObj->pPtr_rd++; + if (pObj->pPtr_rd == pEnd) + pObj->pPtr_rd = pObj->pBuf; + + size--; + } + + return cnt; +} + +UINT32 fifo_write(fifo_t *pObj, UINT8 *pData, UINT32 size, UINT32 timeout, UINT32 do_block) +{ + UINT32 wait_4ever, timeout_cnt, cnt; + UINT8 *pEnd; + + pEnd = pObj->pBuf + pObj->size; + wait_4ever = (timeout == 0); + + cnt = 0; + while(size) + { + timeout_cnt = timeout; + + while(fifo_is_full(pObj)) + { + if (!do_block) + return cnt; + + if (!wait_4ever) + { + if (timeout_cnt) + { + timeout_cnt--; + sleep(1); + } + else + { + return cnt; + } + } + } + + if (pData) + *(pObj->pPtr_wr) = pData[cnt]; + + cnt++; + pObj->pPtr_wr++; + if (pObj->pPtr_wr == pEnd) + pObj->pPtr_wr = pObj->pBuf; + + size--; + } + + return cnt; +} + +// --------------------------------------------------------- diff --git a/lib/CPUs/MIPS/bsp/examples/hpi.h b/lib/CPUs/MIPS/bsp/examples/hpi.h new file mode 100644 index 0000000..58edabe --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/hpi.h @@ -0,0 +1,384 @@ +#ifndef HPI_H +#define HPI_H + +// --------------------------------------------------------- +// API related +// --------------------------------------------------------- +//#define IS_ERROR(e) (0 != (e & HPI_ERROR)) +#define HPI_NOERROR 0 +#define HPI_ERROR 0x80000000 +#define HPI_ERR_NOTIMPL (HPI_ERROR + 1) +#define HPI_ERR_INVPARAM (HPI_ERROR + 2) +#define HPI_ERR_TIMEOUT (HPI_ERROR + 3) +#define HPI_ERR_PREFIX_MBX (HPI_ERROR + 0x00010000) + +#define MAX_NUM_REGS 14 +#define R0 0 +#define R1 1 +#define R2 2 +#define R3 3 +#define R4 4 +#define R5 5 +#define R6 6 +#define R7 7 +#define R8 8 +#define R9 9 +#define R10 10 +#define R11 11 +#define R12 12 +#define R13 13 + +#define USB_MAX_NUM_PORTS 2 +#define USB_MAX_NUM_EPT 8 +#define USB_MAX_IMG_SIZE 512 +#define USB_IRP_BASE 0x0F80 +#define USB_IMG_BASE 0x1000 + +typedef void (*fp_t)(void*); + +// Receive buffer on EP +typedef struct _scy_req_t +{ + UINT16 next; + UINT16 addr; + UINT16 size; + UINT16 callback; +} cy_req_t; + +typedef struct _sfifo_t +{ + UINT32 size; + UINT8 *pBuf; + UINT8 * volatile pPtr_wr, * volatile pPtr_rd; + +} fifo_t; + +typedef struct _susb_irp_t +{ + UINT16 tsize; + UINT32 is_in, is_out; + UINT32 port, ept; + UINT16 cy_irp_addr; + fifo_t fifo; + UINT32 tx_in_progress; + cy_req_t cy_req; +} usb_irp_t; + +// --------------------------------------------------------- +// CY7C67300 related +// --------------------------------------------------------- +#define HPI_WAITACK 1 +#define HPI_NOWAIT 0 + +// --------------------------------------------------------- +// HPI status flags +#define HPI_STATUS_MBX_IN 0x0001 +#define HPI_STATUS_RESET1 0x0002 +#define HPI_STATUS_DONE1 0x0004 +#define HPI_STATUS_DONE2 0x0008 +#define HPI_STATUS_SIEMSG1 0x0010 +#define HPI_STATUS_SIEMSG2 0x0020 +#define HPI_STATUS_RESUME1 0x0040 +#define HPI_STATUS_RESUME2 0x0080 +#define HPI_STATUS_MBX_OUT 0x0100 +#define HPI_STATUS_RESET2 0x0200 +#define HPI_STATUS_SOFEOP1 0x0400 +#define HPI_STATUS_SOFEOP2 0x1000 +#define HPI_STATUS_ID 0x4000 +#define HPI_STATUS_VBUS 0x8000 + +// --------------------------------------------------------- +// LCP command codes +#define COMM_RESET 0xFA50 +#define COMM_JUMP2CODE 0xCE00 +#define COMM_EXEC_INT 0xCE01 +#define COMM_READ_CTRL_REG 0xCE02 +#define COMM_WRITE_CTRL_REG 0xCE03 +#define COMM_CALL_CODE 0xCE04 +#define COMM_READ_XMEM 0xCE05 +#define COMM_WRITE_XMEM 0xCE06 +#define C0MM_CONFIG 0xCE07 +#define COMM_READ_MEM 0xCE08 +#define COMM_WRITE_MEM 0xCE09 +// LCP response codes +#define COMM_ACK 0x0FED +#define COMM_NAK 0xDEAD +#define COMM_ASYNC 0xF00D + +// --------------------------------------------------------- +// LCP memory addresses +#define COMM_PORT_CMD 0x01BA // For PORT Command +#define COMM_MEM_ADDR 0x01BC // Address for COMM_RD/WR_MEM +#define COMM_MEM_LEN 0x01BE // Address for COMM_RD/WR_MEM +#define COMM_LAST_DATA 0x01C0 // memory pointer for xmem +#define COMM_CTRL_REG_ADDR 0x01BC // Address for COMM_RD/WR_CTRL_REG +#define COMM_CTRL_REG_DATA 0x01BE // Address for COMM_RD/WR_CTRL_REG +#define COMM_CTRL_REG_LOGIC 0x01C0 // Address used for AND/OR +#define REG_WRITE_FLG 0x0000 // Value for COMM_CTRL_REG_LOGIC +#define REG_AND_FLG 0x0001 // Value for COMM_CTRL_REG_LOGIC +#define REG_OR_FLG 0x0002 // Value for COMM_CTRL_REG_LOGIC +#define COMM_TIMEOUT 0x01BE // Address setting Timeout for sending response to host +#define COMM_CODE_ADDR 0x01BC // Address for COMM_CALL_CODE and COMM_JUMP2CODE +#define COMM_INT_NUM 0x01C2 // Address used for COMM_EXEC_INT +#define COMM_R0 0x01C4 // CY16-R0 register +#define COMM_R1 0x01C6 // CY16-R1 register +#define COMM_R2 0x01C8 // CY16-R2 register +#define COMM_R3 0x01CA // CY16-R3 register +#define COMM_R4 0x01CC // CY16-R4 register +#define COMM_R5 0x01CE // CY16-R5 register +#define COMM_R6 0x01D0 // CY16-R6 register +#define COMM_R7 0x01D2 // CY16-R7 register +#define COMM_R8 0x01D4 // CY16-R8 register +#define COMM_R9 0x01D6 // CY16-R9 register +#define COMM_R10 0x01D8 // CY16-R10 register +#define COMM_R11 0x01DA // CY16-R11 register +#define COMM_R12 0x01DC // CY16-R12 register +#define COMM_R13 0x01DE // CY16-R13 register + +// for COMM_CTRL_REG_LOGIC +#define LOGIC_DIRECT 0 +#define LOGIC_AND 1 +#define LOGIC_OR 2 + +// --------------------------------------------------------- +// Software interrupts +#define SUSB_INIT_INT 113 +// USB 1 +#define SUSB1_DEVICE_DESCRIPTOR_VEC 90 +#define SUSB1_CONFIGURATION_DESCRIPTOR_VEC 91 +#define SUSB1_STRING_DESCRIPTOR_VEC 92 +#define SUSB1_FINISH_INT 89 +#define SUSB1_STALL_INT 82 +#define SUSB1_STANDARD_INT 83 +#define SUSB1_SEND_INT 80 +#define SUSB1_RECEIVE_INT 81 +#define SUSB1_VENDOR_INT 85 +#define SUSB1_CLASS_INT 87 +#define SUSB1_LOADER_INT 94 +#define SUSB1_DELTA_CONFIG_INT 95 + +// USB 2 +#define SUSB2_DEVICE_DESCRIPTOR_VEC 106 +#define SUSB2_CONFIGURATION_DESCRIPTOR_VEC 107 +#define SUSB2_STRING_DESCRIPTOR_VEC 108 +#define SUSB2_FINISH_INT 105 +#define SUSB2_STALL_INT 98 +#define SUSB2_STANDARD_INT 99 +#define SUSB2_SEND_INT 96 +#define SUSB2_RECEIVE_INT 97 +#define SUSB2_VENDOR_INT 101 +#define SUSB2_CLASS_INT 103 +#define SUSB2_LOADER_INT 110 +#define SUSB2_DELTA_CONFIG_INT 111 + +// --------------------------------------------------------- +// General USB Registers +#define USB_REG_FLAGS 0xC000 // CPU Flags +#define USB_REG_BANK 0xC002 // Register Bank +#define USB_REG_REVISON 0xC004 // Hardware Revision +#define USB_REG_SPEED 0xC008 // CPU Speed +#define USB_REG_PWRCTRL 0xC00A // Power Control +#define USB_REG_INTEN 0xC00E // Interrupt Enable +#define USB_REG_BP 0xC014 // Breakpoint +#define USB_REG_USBDIAG 0xC03C // USB Diagnostic +#define USB_REG_MEMDIAG 0xC03E // Memory Diagnostic + +// HPI registers +#define HPI_REG_BP 0x0140 // HPI Breakpoint +#define HPI_REG_INTROUTE 0x0142 // Interrupt Routing +#define HPI_REG_SIE1MSG 0x0144 // SIE1msg +#define HPI_REG_SIE2MSG 0x0148 // SIE2msg +#define HPI_REG_MAILBOX 0xC0C6 // HPI Mailbox + +// --------------------------------------------------------- +// General Device Registers +// Device 1 +#define SUSB1_REG_PORTSEL 0xC084 // Port select +#define SUSB1_REG_USBCTRL 0xC08A // USB control +#define SUSB1_REG_INTEN 0xC08C // Interrupt enable +#define SUSB1_REG_ADDR 0xC08E // Address +#define SUSB1_REG_STATUS 0xC090 // Status +#define SUSB1_REG_FRAMENUM 0xC092 // Frame number +#define SUSB1_REG_SOFEOPCNT 0xC094 // SOF/EOP count + +// Device 2 +#define SUSB2_REG_PORTSEL 0xC0A4 // Port select +#define SUSB2_REG_USBCTRL 0xC0AA // USB control +#define SUSB2_REG_INTEN 0xC0AC // Interrupt enable +#define SUSB2_REG_ADDR 0xC0AE // Address +#define SUSB2_REG_STATUS 0xC0B0 // Status +#define SUSB2_REG_FRAMENUM 0xC0B2 // Frame number +#define SUSB2_REG_SOFEOPCNT 0xC0B4 // SOF/EOP count + +// --------------------------------------------------------- +// Endpoint Registers +// Device 1 Control +#define SUSB1_REG_EP_CTRL0 0x0200 +#define SUSB1_REG_EP_CTRL1 0x0210 +#define SUSB1_REG_EP_CTRL2 0x0220 +#define SUSB1_REG_EP_CTRL3 0x0230 +#define SUSB1_REG_EP_CTRL4 0x0240 +#define SUSB1_REG_EP_CTRL5 0x0250 +#define SUSB1_REG_EP_CTRL6 0x0260 +#define SUSB1_REG_EP_CTRL7 0x0270 +// Device 1 Address +#define SUSB1_REG_EP_ADDR0 0x0202 +#define SUSB1_REG_EP_ADDR1 0x0212 +#define SUSB1_REG_EP_ADDR2 0x0222 +#define SUSB1_REG_EP_ADDR3 0x0232 +#define SUSB1_REG_EP_ADDR4 0x0242 +#define SUSB1_REG_EP_ADDR5 0x0252 +#define SUSB1_REG_EP_ADDR6 0x0262 +#define SUSB1_REG_EP_ADDR7 0x0272 +// Device 1 Count +#define SUSB1_REG_EP_COUNT0 0x0204 +#define SUSB1_REG_EP_COUNT1 0x0214 +#define SUSB1_REG_EP_COUNT2 0x0224 +#define SUSB1_REG_EP_COUNT3 0x0234 +#define SUSB1_REG_EP_COUNT4 0x0244 +#define SUSB1_REG_EP_COUNT5 0x0254 +#define SUSB1_REG_EP_COUNT6 0x0264 +#define SUSB1_REG_EP_COUNT7 0x0274 +// Device 1 Status +#define SUSB1_REG_EP_STATUS0 0x0206 +#define SUSB1_REG_EP_STATUS1 0x0216 +#define SUSB1_REG_EP_STATUS2 0x0226 +#define SUSB1_REG_EP_STATUS3 0x0236 +#define SUSB1_REG_EP_STATUS4 0x0246 +#define SUSB1_REG_EP_STATUS5 0x0256 +#define SUSB1_REG_EP_STATUS6 0x0266 +#define SUSB1_REG_EP_STATUS7 0x0276 +// Device 1 Count result +#define SUSB1_REG_EP_CNTRES0 0x0208 +#define SUSB1_REG_EP_CNTRES1 0x0218 +#define SUSB1_REG_EP_CNTRES2 0x0228 +#define SUSB1_REG_EP_CNTRES3 0x0238 +#define SUSB1_REG_EP_CNTRES4 0x0248 +#define SUSB1_REG_EP_CNTRES5 0x0258 +#define SUSB1_REG_EP_CNTRES6 0x0268 +#define SUSB1_REG_EP_CNTRES7 0x0278 + +// Device 2 Control +#define SUSB2_REG_EP_CTRL0 0x0280 +#define SUSB2_REG_EP_CTRL1 0x0290 +#define SUSB2_REG_EP_CTRL2 0x02A0 +#define SUSB2_REG_EP_CTRL3 0x02B0 +#define SUSB2_REG_EP_CTRL4 0x02C0 +#define SUSB2_REG_EP_CTRL5 0x02D0 +#define SUSB2_REG_EP_CTRL6 0x02E0 +#define SUSB2_REG_EP_CTRL7 0x02F0 +// Device 2 Address +#define SUSB2_REG_EP_ADDR0 0x0282 +#define SUSB2_REG_EP_ADDR1 0x0292 +#define SUSB2_REG_EP_ADDR2 0x02A2 +#define SUSB2_REG_EP_ADDR3 0x02B2 +#define SUSB2_REG_EP_ADDR4 0x02C2 +#define SUSB2_REG_EP_ADDR5 0x02D2 +#define SUSB2_REG_EP_ADDR6 0x02E2 +#define SUSB2_REG_EP_ADDR7 0x02F2 +// Device 2 Count +#define SUSB2_REG_EP_COUNT0 0x0284 +#define SUSB2_REG_EP_COUNT1 0x0294 +#define SUSB2_REG_EP_COUNT2 0x02A4 +#define SUSB2_REG_EP_COUNT3 0x02B4 +#define SUSB2_REG_EP_COUNT4 0x02C4 +#define SUSB2_REG_EP_COUNT5 0x02D4 +#define SUSB2_REG_EP_COUNT6 0x02E4 +#define SUSB2_REG_EP_COUNT7 0x02F4 +// Device 2 Status +#define SUSB2_REG_EP_STATUS0 0x0286 +#define SUSB2_REG_EP_STATUS1 0x0296 +#define SUSB2_REG_EP_STATUS2 0x02A6 +#define SUSB2_REG_EP_STATUS3 0x02B6 +#define SUSB2_REG_EP_STATUS4 0x02C6 +#define SUSB2_REG_EP_STATUS5 0x02D6 +#define SUSB2_REG_EP_STATUS6 0x02E6 +#define SUSB2_REG_EP_STATUS7 0x02F6 +// Device 2 Count result +#define SUSB2_REG_EP_CNTRES0 0x0288 +#define SUSB2_REG_EP_CNTRES1 0x0298 +#define SUSB2_REG_EP_CNTRES2 0x02A8 +#define SUSB2_REG_EP_CNTRES3 0x02B8 +#define SUSB2_REG_EP_CNTRES4 0x02C8 +#define SUSB2_REG_EP_CNTRES5 0x02D8 +#define SUSB2_REG_EP_CNTRES6 0x02E8 +#define SUSB2_REG_EP_CNTRES7 0x02F8 + +// --------------------------------------------------------- +// others +#define HUSB_TDLISTDONE 0x1000 +#define HUSB_SOF 0x2000 +#define HUSB_ARMV 0x0001 +#define HUSB_AINS_FS 0x0002 +#define HUSB_AINS_LS 0x0004 +#define HUSB_AWAKEUP 0x0008 +#define HUSB_BRMV 0x0010 +#define HUSB_BINS_FS 0x0020 +#define HUSB_BINS_LS 0x0040 +#define HUSB_BWAKEUP 0x0080 + +#define SUSB_EP0_MSG 0x0001 +#define SUSB_EP1_MSG 0x0002 +#define SUSB_EP2_MSG 0x0004 +#define SUSB_EP3_MSG 0x0008 +#define SUSB_EP4_MSG 0x0010 +#define SUSB_EP5_MSG 0x0020 +#define SUSB_EP6_MSG 0x0040 +#define SUSB_EP7_MSG 0x0080 +#define SUSB_RST_MSG 0x0100 +#define SUSB_SOF_MSG 0x0200 +#define SUSB_CFG_MSG 0x0400 +#define SUSB_SUS_MSG 0x0800 +#define SUSB_ID_MSG 0x4000 +#define SUSB_VBUS_MSG 0x8000 + +// --------------------------------------------------------- +// Functions +// --------------------------------------------------------- + +// HPI low-level routines +void cy67k3_isr(void); +void cy67k3_reset(void); +UINT16 cy67k3_read_HPI_DATA(void); +UINT16 cy67k3_read_HPI_MAILBOX(void); +UINT16 cy67k3_read_HPI_ADDRESS(void); +UINT16 cy67k3_read_HPI_STATUS(void); +void cy67k3_write_HPI_DATA(UINT16 data); +void cy67k3_write_HPI_MAILBOX(UINT16 data); +void cy67k3_write_HPI_ADDRESS(UINT16 data); +void cy67k3_write_HPI_STATUS(UINT16 data); + +// HPI API +UINT32 hpi_init(void); +void hpi_mbx_write(UINT16 msgcode); +UINT32 hpi_mbx_read(void); +UINT32 hpi_read_reg(UINT16 addr); +UINT32 hpi_write_reg(UINT16 addr, UINT16 data); +UINT32 hpi_write_ram(UINT16 addr, UINT16 *pData, UINT32 num_words); +UINT32 hpi_read_ram(UINT16 addr, UINT16 *pData, UINT32 num_words); +UINT32 hpi_comm_reset(void); +UINT32 hpi_comm_jump2code(UINT16 addr); +UINT32 hpi_comm_callcode(UINT16 addr); +UINT32 hpi_comm_write_ctrl_reg(UINT16 addr, UINT16 data, UINT16 logic); +UINT32 hpi_comm_read_ctrl_reg(UINT16 addr); +UINT32 hpi_comm_write_xmem(UINT16 addr, UINT8 *pData, UINT16 len); +UINT32 hpi_comm_read_xmem(UINT16 addr, UINT8 *pData, UINT16 len); +UINT32 hpi_comm_exec_int(UINT16 intnum, UINT32 nargs, ...); + +// USB API +UINT32 usb_init(void); +UINT32 usb_irp_register(usb_irp_t *pIRP, UINT32 port, UINT32 ept, UINT32 size, UINT32 is_out); +UINT32 usb_irp_enqueue(usb_irp_t *pIRP); +UINT32 usb_callback_register(UINT32 port, UINT32 type, fp_t pFunc, void *pArg); + +#define FIFO_BLOCK 1 +#define FIFO_NONBLOCK 0 +UINT32 fifo_alloc(fifo_t *pObj, UINT32 size); +UINT32 fifo_free(fifo_t *pObj); +UINT32 fifo_flush(fifo_t *pObj); +UINT32 fifo_is_full(fifo_t *pObj); +UINT32 fifo_is_empty(fifo_t *pObj); +UINT32 fifo_read(fifo_t *pObj, UINT8 *pData, UINT32 size, UINT32 timeout, UINT32 do_block); +UINT32 fifo_write(fifo_t *pObj, UINT8 *pData, UINT32 size, UINT32 timeout, UINT32 do_block); + +#endif // HPI_H diff --git a/lib/CPUs/MIPS/bsp/examples/inflate.c b/lib/CPUs/MIPS/bsp/examples/inflate.c new file mode 100644 index 0000000..b50581d --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/inflate.c @@ -0,0 +1,504 @@ +/* inflate routines for Palm OS (to inflate a deflated stream) + * + * Based heavily upon gunzip.c by Pasi Ojala + * http://www.cs.tut.fi/~albert/Dev/gunzip/ + * Many, many thanks for that code! + * + * Changes: + * 2002-12-30 - Added #defines to use zlib's struct instead of mine, just + * in case you want to compile it that way. + * 2002-12-29 - Found out that this is VERY slow. ZLib is 3x faster. + * Worked on speeding it up. Partially successful. Profiled + * code and marked critical areas. 1932 bytes added to a + * Palm program by linking in the .o file. Schweet! + * 2002-12-21 - Finished surgery. Only one function to inflate dynamic and + * fixed data. Rewrote table generation to be iterative. + * Hacked and slashed my way through unnecessary code. + * The size is now down to 3512 bytes. + * 2002-12-20 - Started major surgery + * 2002-12-19 - Looked at the code a bit more + * 2002-12-17 - Continued work. Down to about 6k for the .o file + * 2002-12-09 - Continued work, added z_stream_fid instead of globals + * 2002-12-08 - Started work so that it decompresses up to 64k (one memory + * chunk on the Palm. + * 2002-12-07 - Removed bit reverse table. Removed unzip code. + */ +#include "libsys.h" +#include "inflate.h" +#ifdef VERBOSE +#include // Just in case you put a printf() function back in +#endif + +void Status(char *, int); + +typedef struct HufNode_struct { + // b0 and b1 are either values in the tree array to jump to (branches) + // or are literal values. + // if (bX & 0x8000) + // value = bX ^ 0x8000; + // else + // link_to_array_element = bX; + unsigned int b0; // Bigger than 1 byte (2 is ideal) + unsigned int b1; // Bigger than 1 byte (2 is ideal) +} HufNode; + + +// Not that rhobust anymore -- If out of data, this will +// return a whole lot of 1 bits. +// +// This function consumes a large percentage of time (#1) +char READBIT(z_stream *zs) +{ + char carry; + + if (zs->reserved == 1) + { + if (zs->avail_in == 0) + return 1; + zs->reserved = *(zs->next_in ++) | 0x0100; + zs->avail_in --; + } + + carry = zs->reserved & 1; + zs->reserved >>= 1; + + return carry; +} + + +// Make sure that [a] is <= 16 +// If there are endian problems, force [a] to be <= 8 +// Might be faster if all (up to [a] bits) of zs->reserved was read into res +// right away. +// +// This function consumes a large percentage of time (#4) +int READBITS(z_stream *zs, int a) +{ + int res = 0, pos = 0; + + while (a --) + { + if (zs->reserved == 1) + { + if (zs->avail_in == 0) + return 1; + zs->reserved = *(zs->next_in ++) | 0x0100; + zs->avail_in --; + } + + res += (zs->reserved & 1) << pos; + zs->reserved >>= 1; + pos ++; + } + + return res; +} + + +// Huffman tree structures, variables and related routines +// +// These routines are one-bit-at-a-time decode routines. They +// are not as fast as multi-bit routines, but maybe a bit easier +// to understand and use a lot less memory. +// +// The tree is created in an array +// +// currentTree = where to put the tree (in an array) +// numval = Number of elements in the lengths array +// lengths = array of lengths +// +// +// This function consumes a large percentage of time (#5) +int CreateTree(HufNode *currentTree, int numval, unsigned char *lengths) { + int i, j, len; // basically scratch values + int BlankNode; // Where is the next blank array index + int this_code, mask, *bitData; // used in tree generation + int bl_count[16] = { 0, }; // Counter of code lengths + int next_code[16] = { 0, }; // Code for a specific length + // 16 = (15 is max length of a code when inflating) + (1 for zero) + + // Step 1: Count the code lengths + for (i = 0; i < numval; i ++) + { + j = lengths[i]; + if (j > 15) + return 1; + bl_count[j] ++; + } + + // Step 2: Find numerical value of the smallest code of each length + // Also note that I've inserted some weak validation code here. I'm + // not 100% sure that it is up to RFC specs, but it seems to work fine + // in my tests + // + // The validation theory is that at the root node, you have 2 branches or + // values possible. If you branch, you get 2 more potentials. If you + // get a value, you lose one potential. So, if the root node has one of + // each, the number of potentials at the next level is still two. If that + // node just has branches, the number of potentials is four. If both of + // the nodes on the following level just have values, the number of + // potentials is 0, leaving us with a complete tree. + // + // If I don't validate and if an invalid tree gets generated, an + // infinite loop is possible + bl_count[0] = 0; + j = 0; + len = 2; + for (i = 1; i < 16; i ++) + { + len -= bl_count[i]; + len *= 2; + j = (j + bl_count[i - 1]) << 1; + next_code[i] = j; + } + if (len) + return 1; + + // Step 3: Assign numerical values to all codes + BlankNode = 1; + currentTree[0].b0 = 0x0000; + currentTree[0].b1 = 0x0000; + for (i = 0; i < numval; i ++) + { + len = lengths[i]; + if (len != 0) + { + this_code = next_code[len]; + next_code[len] ++; + mask = 1 << (len - 1); + j = 0; + while (mask > 1) + { + if (this_code & mask) + bitData = &(currentTree[j].b1); + else + bitData = &(currentTree[j].b0); + + if (*bitData == 0x0000) + { + *bitData = BlankNode; + j = BlankNode; + BlankNode ++; + currentTree[j].b0 = 0x0000; + currentTree[j].b1 = 0x0000; + } + else + j = *bitData; + + mask >>= 1; + } + if (this_code & 0x01) + currentTree[j].b1 = 0x8000 | i; + else + currentTree[j].b0 = 0x8000 | i; + } + } + +#ifdef VERBOSE + fprintf(stderr, "%d table entries used\n", + BlankNode); + if (numval < 20) { + for (i = 0; i < BlankNode; i ++) + { + fprintf(stderr, "0x%03x - ", i); + if (currentTree[i].b0 & 0x8000) + fprintf(stderr, "value: 0x%03x ", currentTree[i].b0 ^ 0x8000); + else + fprintf(stderr, " link: 0x%03x ", currentTree[i].b0); + + if (currentTree[i].b1 & 0x8000) + fprintf(stderr, "value: 0x%03x\n", currentTree[i].b1 ^ 0x8000); + else + fprintf(stderr, " link: 0x%03x\n", currentTree[i].b1); + } + } +#endif + + return 0; +} + + +// Using the tree passed in, read bits from the data stream until we arrive +// at the proper value +// +// This function consumes a large percentage of time (#2) +int DecodeValue(z_stream *zs, HufNode *currentTree) +{ + unsigned int i = 0; + + // decode one symbol of the data per iteration + // Infinite loop detection code could go here. Maximum + // bits to read is 15. + while (i < 0x8000) + { + if (READBIT(zs)) + i = currentTree[i].b1; + else + i = currentTree[i].b0; + } + return i & 0x7FFF; +} + + +int Decompress_Stored(z_stream *zs) +{ + int blockLen, cSum; + +#ifdef VERBOSE + fprintf(stderr, "Stored\n"); +#endif + + zs->reserved = 1;; + if (zs->avail_in < 4) + return -1; + + zs->avail_in -= 4; + blockLen = *(zs->next_in ++); + blockLen |= *(zs->next_in ++) << 8; + + cSum = *(zs->next_in ++); + cSum |= (*(zs->next_in ++) << 8); + + if ((blockLen + cSum) ^ 0xFFFF) + return 1; + if (zs->avail_in < blockLen || zs->avail_out < blockLen) + return -1; + zs->avail_in -= blockLen; + zs->avail_out -= blockLen; + + while (blockLen --) + { + *(zs->next_out) = *(zs->next_in); + zs->next_out ++; + zs->next_in ++; + } + + return 0; +} + + +int MakeTrees(z_stream *zs, char is_fixed, HufNode *literalTree, + HufNode *distanceTree) +{ + // Order of the bit length code lengths + static const unsigned border[] = { + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; + unsigned char ll[288+32]; + int i, j, n, l, literalCodes, distCodes; + + if (is_fixed) + { + literalCodes = 288; + + // Set a large range to 8 + for (i = 0; i < 288; i ++) + ll[i] = 8; + // In that range, set some to 9 and others to 7 + // (smaller code, but slightly slower table generation) + for (i = 144; i < 256; i ++) + ll[i] = 9; + for (; i < 280; i ++) + ll[i] = 7; + + distCodes = 32; + + for (i = 288; i < 320; i ++) + ll[i] = 5; + } + else + { + literalCodes = 257 + READBITS(zs, 5); + distCodes = 1 + READBITS(zs, 5); + l = 4 + READBITS(zs, 4); + + for (j = 0; j < 19; j ++) + ll[j] = 0; + + // Get the decode tree code lengths + // The decode tree is Huffman encoded + + for (j = 0; j < l; j++) + { + ll[border[j]] = READBITS(zs, 3); + } + if (CreateTree(distanceTree, 19, ll)) + return 1; + + // read in literal and distance code lengths + n = literalCodes + distCodes; + i = 0; + while (i < n) + { + j = DecodeValue(zs, distanceTree); + if (j < 16) // length of code in bits (0..15) + ll[i++] = j; + else if (j == 16) + { // repeat last length 3 to 6 times + j = 3 + READBITS(zs, 2); + + if (i + j > n) + return 1; + + l = i ? ll[i-1] : 0; + while (j --) + ll[i++] = l; + } + else + { + if (j == 17) // 3 to 10 zero length codes + j = 3 + READBITS(zs, 3); + else // j == 18: 11 to 138 zero length codes + j = 11 + READBITS(zs, 7); + + if (i + j > n) + return 1; + + while (j --) + ll[i++] = 0; + } + } + } + + + // Can overwrite tree decode tree as it is not used anymore + if (CreateTree(literalTree, literalCodes, &ll[0])) + return 1; + + if(CreateTree(distanceTree, distCodes, &ll[literalCodes])) + return 1; + + return 0; +} + + +// This function consumes a large percentage of time (#3) +// Most output produced by gzip/zlib/etc is dynamic. +int Decompress_DynamicOrFixed(z_stream *zs, char is_fixed) +{ + // Copy lengths for literal codes 257..285 + static const unsigned short cplens[] = { + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 }; + // Extra bits for literal codes 257..285 + static const unsigned short cplext[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99 }; // 99==invalid + // Copy offsets for distance codes 0..29 + static const unsigned short cpdist[] = { + 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0007, 0x0009, 0x000d, + 0x0011, 0x0019, 0x0021, 0x0031, 0x0041, 0x0061, 0x0081, 0x00c1, + 0x0101, 0x0181, 0x0201, 0x0301, 0x0401, 0x0601, 0x0801, 0x0c01, + 0x1001, 0x1801, 0x2001, 0x3001, 0x4001, 0x6001 }; + // Extra bits for distance codes + static const unsigned short cpdext[] = { + 0, 0, 0, 0, 1, 1, 2, 2, + 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, + 11, 11, 12, 12, 13, 13 }; + HufNode literalTree[288]; + HufNode distanceTree[32]; + int j, l, dist; + +#ifdef VERBOSE + if (is_fixed) + fprintf(stderr, "Fixed Huffman codes\n"); + else + fprintf(stderr, "Dynamic Huffman codes\n"); +#endif + + if (MakeTrees(zs, is_fixed, literalTree, distanceTree)) + return 1; + + while (1) + { + j = DecodeValue(zs, literalTree); + if (j >= 256) + { + if (j == 256) // EOF + break; + + //printf("%04x ", j); + j -= 256 + 1; // bytes + EOF + + l = READBITS(zs, cplext[j]) + cplens[j]; + //printf("%04x ", l); + + j = DecodeValue(zs, distanceTree); + //printf("%02x ", j); + + dist = READBITS(zs, cpdext[j]) + cpdist[j]; + //printf("%04x ", dist); + + //printf("LZ77 len %d dist %d @%04x\n", l, dist, bIdx); + while(l--) + { + //printf("%02x ", c); + if (! zs->avail_out --) + return -1; + + *(zs->next_out ++) = *(zs->next_out - dist); + } + //printf("\n"); + } + else + { + //printf("%02x\n", j); + if (! zs->avail_out --) + return -1; + *(zs->next_out ++) = (unsigned char) j; + } + } + return 0; +} + + +// Returns 0 if success +int InflateData(z_stream *zs) { + int last, type; + + zs->reserved = 1;; + + do + { + last = READBIT(zs); +#ifdef VERBOSE + if (last) + fprintf(stderr, "Last Block: "); + else + fprintf(stderr, "Not Last Block: "); +#endif + + type = READBITS(zs, 2); + + if (type == 0) + { +#ifdef VERBOSE + fprintf(stderr, "Decompress_Stored.."); +#endif + if (Decompress_Stored(zs)) + return 1; + } + else if (type > 2) + { +#ifdef VERBOSE + if (type == 3) + fprintf(stderr, "Reserved block type!!\n"); + else // the "else" should never happen + fprintf(stderr, "Unexpected value %d!\n", type); +#endif + zs->reserved = 1;; + return 1; + } + else + { +#ifdef VERBOSE + fprintf(stderr, "Decompress_DynamicOrFixed.."); +#endif + if (Decompress_DynamicOrFixed(zs, type & 0x01)) + return 1; + } + } while(!last); + + zs->reserved = 1;; + return 0; +} diff --git a/lib/CPUs/MIPS/bsp/examples/inflate.h b/lib/CPUs/MIPS/bsp/examples/inflate.h new file mode 100644 index 0000000..1f6fd38 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/inflate.h @@ -0,0 +1,15 @@ +#ifdef USE_ZLIB_STRUCT +#include "SysZLib.h" // For PalmOS. Change to your liking. +#else +typedef struct z_stream_s +{ + unsigned char *next_in; // Next input byte (CHANGES) + unsigned int avail_in; // number of bytes left at next_in + unsigned char *next_out; // Next output byte goes here (CHANGES) + unsigned int avail_out; // number of bytes left at next_out + unsigned int reserved; // For the readbit() and readbits() functions + // Bigger than 1 byte +} z_stream; +#endif + +int InflateData(z_stream *zs); diff --git a/lib/CPUs/MIPS/bsp/examples/isqrt.c b/lib/CPUs/MIPS/bsp/examples/isqrt.c new file mode 100644 index 0000000..6022fc1 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/isqrt.c @@ -0,0 +1,89 @@ +/* +++Date last modified: 05-Jul-1997 */ + +#include +#include "snipmath.h" + +#define BITSPERLONG 32 + +#define TOP2BITS(x) ((x & (3L << (BITSPERLONG-2))) >> (BITSPERLONG-2)) + + +/* usqrt: + ENTRY x: unsigned long + EXIT returns floor(sqrt(x) * pow(2, BITSPERLONG/2)) + + Since the square root never uses more than half the bits + of the input, we use the other half of the bits to contain + extra bits of precision after the binary point. + + EXAMPLE + suppose BITSPERLONG = 32 + then usqrt(144) = 786432 = 12 * 65536 + usqrt(32) = 370727 = 5.66 * 65536 + + NOTES + (1) change BITSPERLONG to BITSPERLONG/2 if you do not want + the answer scaled. Indeed, if you want n bits of + precision after the binary point, use BITSPERLONG/2+n. + The code assumes that BITSPERLONG is even. + (2) This is really better off being written in assembly. + The line marked below is really a "arithmetic shift left" + on the double-long value with r in the upper half + and x in the lower half. This operation is typically + expressible in only one or two assembly instructions. + (3) Unrolling this loop is probably not a bad idea. + + ALGORITHM + The calculations are the base-two analogue of the square + root algorithm we all learned in grammar school. Since we're + in base 2, there is only one nontrivial trial multiplier. + + Notice that absolutely no multiplications or divisions are performed. + This means it'll be fast on a wide range of processors. +*/ + +void usqrt(unsigned long x, struct int_sqrt *q) +{ + unsigned long a = 0L; /* accumulator */ + unsigned long r = 0L; /* remainder */ + unsigned long e = 0L; /* trial product */ + + int i; + + for (i = 0; i < BITSPERLONG; i++) /* NOTE 1 */ + { + r = (r << 2) + TOP2BITS(x); x <<= 2; /* NOTE 2 */ + a <<= 1; + e = (a << 1) + 1; + if (r >= e) + { + r -= e; + a++; + } + } + memcpy(q, &a, sizeof(long)); +} + +#ifdef TEST + +#include +#include + +main(void) +{ + int i; + unsigned long l = 0x3fed0169L; + struct int_sqrt q; + + for (i = 0; i < 101; ++i) + { + usqrt(i, &q); + printf("sqrt(%3d) = %2d, remainder = %2d\n", + i, q.sqrt, q.frac); + } + usqrt(l, &q); + printf("\nsqrt(%lX) = %X, remainder = %X\n", l, q.sqrt, q.frac); + return 0; +} + +#endif /* TEST */ diff --git a/lib/CPUs/MIPS/bsp/examples/life.c b/lib/CPUs/MIPS/bsp/examples/life.c new file mode 100644 index 0000000..bba5a0e --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/life.c @@ -0,0 +1,251 @@ +/* life.c - demonstrator for later Mips+LCD game of life + * + * 23.03.06 - MACRO-based version + * 22.02.06 - new file + */ + +//#include "ks0108.h" + +#include +#include +#include +#include "libsys.h" + + +#define NX 200 // 70 // 128 // 48 // 128 +#define NY 150 // 31 // 64 // 27 // 64 + +#define SCREEN_X 800 +#define SCREEN_Y 600 + +#define SCALE_X (4) +#define SCALE_Y (4) +#define OFFSET_X ((SCREEN_X-(SCALE_X*NX))/2) +#define OFFSET_Y ((SCREEN_Y-(SCALE_Y*NY))/2) + +// OCCUPIED must be uneven, EMPTY even. +#define OCCUPIED 0x77771111 +#define EMPTY 0xeeee0000 + +#define MATRIX( row, col ) (*(matrix + (NX*col) + row )) +#define FUTURE( row, col ) (*(future + (NX*col) + row )) + +UINT32 *g_gx_buff; + +int clock_lfsr32() +{ + return rand(); +} + + +/* return a pseudo-random integer in the range 0..1023 */ +int random1023() { + int tmp; + + tmp = clock_lfsr32(); + return tmp & 0x000003ff; +} + +typedef struct _scolor_t +{ + UINT8 r, g, b, a; +} __attribute__ ((__packed__)) color_t; + + +void DrawPixel(UINT32 x, UINT32 y, color_t *pColor) +{ + int i, j; + for (i=0; i < SCALE_Y; i++) + for (j=0; j < SCALE_X; j++) + g_gx_buff[(OFFSET_X+SCALE_X*x+j) + SCREEN_X*(OFFSET_Y+SCALE_Y*y+i)] = *((UINT32*)pColor); +} + + +/* MSB/LSB in y-Richtung vertauscht */ +void displayBoard1( int* matrix ) +{ + int x, y; + int mask, accu; + UINT32 color; + + for( x=0; x < NX; x++ ) + { + mask = 0x80; + accu = 0x00; + for( y=0; y < NY; y++ ) + { + color = (UINT32)-(MATRIX(x,y) & 0x1); + DrawPixel(x, y, (color_t*)&color); +// if (MATRIX( x, y ) != OCCUPIED) +// { +// accu |= mask; +// } +// mask = mask >> 1; + +// color = 0; +// DrawPixel(x, (y>>3), (color_t*)&color); +// if (mask == 0) +// { +// color = accu; +// DrawPixel(x, (y>>3), (color_t*)&color); +// mask = 0x80; +// accu = 0x00; +// } + } +// color = accu; +// DrawPixel(x, (y>>3), (color_t*)&color); + + } +// *(matrix-15) = 0xdead0000; +// *(matrix-16) = *(matrix-16) + 1; +} + +void initializeBoard( int* matrix ) { + int x, y; + for( x=0; x < NX; x++ ) { + for( y=0; y < NY; y++ ) { + int d = random1023(); + if (d > 920) MATRIX( x, y ) = OCCUPIED; + else MATRIX( x, y ) = EMPTY; + } + } +} + + +int countNeighbors( int* matrix, int i, int j ) { + int im = i-1; + int ip = i+1; + + int jm = j-1; + int jp = j+1; + + int n = 0; + // wrap-around + if (ip >= NX) ip = 0; + if (jp >= NY) jp = 0; + + if (im < 0) im = NX-1; + if (jm < 0) jm = NY-1; + + // check eight neighbors + n += MATRIX(im, jm ) & 0x1; // nw + n += MATRIX(im, j ) & 0x1; // west + n += MATRIX(im, jp ) & 0x1; // sw + + n += MATRIX(i, jm ) & 0x1; // north + // n += MATRIX(i, j ) & 0x1; // center + n += MATRIX(i, jp ) & 0x1; // south + + n += MATRIX(ip, jm ) & 0x1; // ne + n += MATRIX(ip, j ) & 0x1; // east + n += MATRIX(ip, jp ) & 0x1; // se + + return n; +} + + +/** + * the actual game of life algorithm: cell is born when three neighbors, + * survives when exactly two live neighbors, dies otherwise. + */ +void nextGeneration( int* matrix, int* future ) { + int i, j; + int lifes = 0; + + for( i=0; i < NX; i++ ) { + for( j=0; j < NY; j++ ) { + // count neighbors + int n = countNeighbors( matrix, i, j ); + + //if ((n != 0) && (random1023() > 990)) { // some slight random offset + // if (random1023() > 500) FUTURE(i,j) = OCCUPIED; + // else FUTURE(i,j) = EMPTY; + //} + // else if (n == 3) FUTURE(i,j) = OCCUPIED; + + if (n == 3) FUTURE(i,j) = OCCUPIED; + else if ((n == 2) && (MATRIX(i,j) == OCCUPIED)) FUTURE(i,j) = OCCUPIED; + else FUTURE(i,j) = EMPTY; + + if (FUTURE(i,j) == OCCUPIED) lifes++; + } + } + // generation ++; + + // avoid extinction :-) + if (lifes < 10) { + // printf( "CREATING A NEW POPULATION\n\n\n" ); + initializeBoard( matrix ); + } + else { // swap buffers: C PROHIBITS ASSIGNING TO ARRAY TYPES + for( i=0; i < NX; i++ ) { + for( j=0; j < NY; j++ ) { + MATRIX(i,j) = FUTURE(i,j); + } + } + } +} + +void gx_init(void) +{ + volatile UINT32 *pVGA_ctrl = (UINT32*)SYS_VGA_CTRL; + volatile UINT32 *pVGA_front = (UINT32*)SYS_VGA_FB_FRONT; + volatile UINT32 *pVGA_back = (UINT32*)SYS_VGA_FB_BACK; + + sleep(500); + + g_gx_buff = (UINT32*)malloc(SCREEN_X*SCREEN_Y*sizeof(UINT32)); + memset(g_gx_buff, 0, SCREEN_X*SCREEN_Y*sizeof(UINT32)); + printf("g_gx_buff : %8.8X\n", (UINT32)g_gx_buff); + + *pVGA_ctrl |= SYS_VGA_BIT_MSTEN; + *pVGA_front = (UINT32)g_gx_buff; + *pVGA_back = (UINT32)g_gx_buff; + +} + +int main( int argc, char* argv[] ) { + + int* ptr, cnt = 0; + + int* matrix; + int* future; + volatile UINT32 *pBtn = (UINT32*)SYS_GPIO0; + + // lcdEnableDisplay( 1 ); + // lcdSetColor( 1 ); + // lcdSetPixel( 0, 0 ); + // lcdSetPixel( 3, 5 ); + + // if we have stdlib: + matrix = (void*) malloc( NX*NY*sizeof(int) ); + future = (void*) malloc( NX*NY*sizeof(int) ); + + + gx_init(); + +// matrix = (void *) 0x00004000; +// future = (void *) 0x00014000; + + // init_lfsr32( 0xcafebabe ); + // init_lfsr32( 0x13 ); + + srand(clock()); + initializeBoard( matrix ); + + while( 1 ) + { + + if (*pBtn) + { + srand(clock()); + initializeBoard( matrix ); + cnt = 0; + } + sputs("Generation #"); print_word(cnt++); sputs("\n"); + displayBoard1( matrix ); + nextGeneration( matrix, future ); + } + + // return 0 +} diff --git a/lib/CPUs/MIPS/bsp/examples/lua_init.c b/lib/CPUs/MIPS/bsp/examples/lua_init.c new file mode 100644 index 0000000..0edd3d5 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/lua_init.c @@ -0,0 +1 @@ +#include "all.c" diff --git a/lib/CPUs/MIPS/bsp/examples/lwl.c b/lib/CPUs/MIPS/bsp/examples/lwl.c new file mode 100644 index 0000000..3905cf0 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/lwl.c @@ -0,0 +1,46 @@ +#include "libsys.h" + +int non_aligned_load(UINT32* pMem) +{ + UINT32 result; + __asm__ + ( + "li $t0, 0x01234567\n" + "li $t1, 0x89ABCDEF\n" + "sw $t0, 0(%[pMem])\n" + "sw $t1, 64(%[pMem])\n" + "lw %[val], 0(%[pMem])\n" + "lw %[val], 64(%[pMem])\n" + "nop\n" + "nop\n" + "nop\n" + "nop\n" + "nop\n" + "nop\n" + "nop\n" + "nop\n" + "nop\n" + "nop\n" + "nop\n" + "nop\n" + "nop\n" + "nop\n" + "nop\n" + "li %[val], 0x55555555\n" + "lw %[val], 0(%[pMem])\n" + "lwl %[val], 65(%[pMem])\n" + : [val] "=r" (result) + : [pMem] "r" (pMem) + ); + return result; +} + +int main() +{ + int buf[256], res, i; + + res = non_aligned_load(buf); + + return res; + +} diff --git a/lib/CPUs/MIPS/bsp/examples/mandelbrot.c b/lib/CPUs/MIPS/bsp/examples/mandelbrot.c new file mode 100644 index 0000000..ce7aa9d --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/mandelbrot.c @@ -0,0 +1,54 @@ +// by Erik Wrenholt +#include +#include + +#define BAILOUT 16 +#define MAX_ITERATIONS 1000 + +int mandelbrot(double x, double y) +{ + double cr = y - 0.5; + double ci = x; + double zi = 0.0; + double zr = 0.0; + int i = 0; + + while(1) { + i ++; + double temp = zr * zi; + double zr2 = zr * zr; + double zi2 = zi * zi; + zr = zr2 - zi2 + cr; + zi = temp + temp + ci; + if (zi2 + zr2 > BAILOUT) + return i; + if (i > MAX_ITERATIONS) + return 0; + } + +} + +int main (int argc, const char * argv[]) { + struct timeval aTv; + gettimeofday(&aTv, NULL); + long init_time = aTv.tv_sec; + long init_usec = aTv.tv_usec; + + int x,y; + for (y = -39; y < 39; y++) { + printf("\n"); + for (x = -39; x < 39; x++) { + int i = mandelbrot(x/40.0, y/40.0); + if (i==0) + printf("*"); + else + printf(" "); + } + } + printf ("\n"); + + gettimeofday(&aTv,NULL); + double query_time = (aTv.tv_sec - init_time) + (double)(aTv.tv_usec - init_usec)/1000000.0; + printf ("C Elapsed %0.2f\n", query_time); + return 0; +} diff --git a/lib/CPUs/MIPS/bsp/examples/paranoia.c b/lib/CPUs/MIPS/bsp/examples/paranoia.c new file mode 100644 index 0000000..38f08e1 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/paranoia.c @@ -0,0 +1,2302 @@ +/* + * paranoia.c,v 1.4 1995/08/23 19:26:32 joel Exp + * + * A C version of Kahan's Floating Point Test "Paranoia" + * + * Thos Sumner, UCSF, Feb. 1985 + * David Gay, BTL, Jan. 1986 + * + * This is a rewrite from the Pascal version by + * + * B. A. Wichmann, 18 Jan. 1985 + * + * (and does NOT exhibit good C programming style). + * + * Sun May 16 18:21:51 MDT 1993 Jeffrey Wheat (cassidy@cygnus.com) + * Removed KR_headers defines, removed ANSI prototyping + * Cleaned up and reformated code. Added special CYGNUS + * "verbose" mode type messages (-DCYGNUS). + * Note: This code is VERY NASTY. + * + * Adjusted to use Standard C headers 19 Jan. 1992 (dmg); + * compile with -DKR_headers or insert + * #define KR_headers + * at the beginning if you have an old-style C compiler. + * + * (C) Apr 19 1983 in BASIC version by: + * Professor W. M. Kahan, + * 567 Evans Hall + * Electrical Engineering & Computer Science Dept. + * University of California + * Berkeley, California 94720 + * USA + * + * converted to Pascal by: + * B. A. Wichmann + * National Physical Laboratory + * Teddington Middx + * TW11 OLW + * UK + * + * converted to C by: + * + * David M. Gay and Thos Sumner + * AT&T Bell Labs Computer Center, Rm. U-76 + * 600 Mountain Avenue University of California + * Murray Hill, NJ 07974 San Francisco, CA 94143 + * USA USA + * + * with simultaneous corrections to the Pascal source (reflected + * in the Pascal source available over netlib). + * [A couple of bug fixes from dgh = sun!dhough incorporated 31 July 1986.] + * + * Reports of results on various systems from all the versions + * of Paranoia are being collected by Richard Karpinski at the + * same address as Thos Sumner. This includes sample outputs, + * bug reports, and criticisms. + * + * You may copy this program freely if you acknowledge its source. + * Comments on the Pascal version to NPL, please. + * + * + * The C version catches signals from floating-point exceptions. + * If signal(SIGFPE,...) is unavailable in your environment, you may + * #define NOSIGNAL to comment out the invocations of signal. + * + * This source file is too big for some C compilers, but may be split + * into pieces. Comments containing "SPLIT" suggest convenient places + * for this splitting. At the end of these comments is an "ed script" + * (for the UNIX(tm) editor ed) that will do this splitting. + * + * By #defining SINGLE_PRECISION when you compile this source, you may + * obtain a single-precision C version of Paranoia. + * + * The following is from the introductory commentary from Wichmann's work: + * + * The BASIC program of Kahan is written in Microsoft BASIC using many + * facilities which have no exact analogy in Pascal. The Pascal + * version below cannot therefore be exactly the same. Rather than be + * a minimal transcription of the BASIC program, the Pascal coding + * follows the conventional style of block-structured languages. Hence + * the Pascal version could be useful in producing versions in other + * structured languages. + * + * Rather than use identifiers of minimal length (which therefore have + * little mnemonic significance), the Pascal version uses meaningful + * identifiers as follows [Note: A few changes have been made for C]: + * + * + * BASIC C BASIC C BASIC C + * + * A J S StickyBit + * A1 AInverse J0 NoErrors T + * B Radix [Failure] T0 Underflow + * B1 BInverse J1 NoErrors T2 ThirtyTwo + * B2 RadixD2 [SeriousDefect] T5 OneAndHalf + * B9 BMinusU2 J2 NoErrors T7 TwentySeven + * C [Defect] T8 TwoForty + * C1 CInverse J3 NoErrors U OneUlp + * D [Flaw] U0 UnderflowThreshold + * D4 FourD K PageNo U1 + * E0 L Milestone U2 + * E1 M V + * E2 Exp2 N V0 + * E3 N1 V8 + * E5 MinSqEr O Zero V9 + * E6 SqEr O1 One W + * E7 MaxSqEr O2 Two X + * E8 O3 Three X1 + * E9 O4 Four X8 + * F1 MinusOne O5 Five X9 Random1 + * F2 Half O8 Eight Y + * F3 Third O9 Nine Y1 + * F6 P Precision Y2 + * F9 Q Y9 Random2 + * G1 GMult Q8 Z + * G2 GDiv Q9 Z0 PseudoZero + * G3 GAddSub R Z1 + * H R1 RMult Z2 + * H1 HInverse R2 RDiv Z9 + * I R3 RAddSub + * IO NoTrials R4 RSqrt + * I3 IEEE R9 Random9 + * + * SqRWrng + * + * All the variables in BASIC are true variables and in consequence, + * the program is more difficult to follow since the "constants" must + * be determined (the glossary is very helpful). The Pascal version + * uses Real constants, but checks are added to ensure that the values + * are correctly converted by the compiler. + * + * The major textual change to the Pascal version apart from the + * identifiersis that named procedures are used, inserting parameters + * wherehelpful. New procedures are also introduced. The + * correspondence is as follows: + * + * + * BASIC Pascal + * lines + * + * 90- 140 Pause + * 170- 250 Instructions + * 380- 460 Heading + * 480- 670 Characteristics + * 690- 870 History + * 2940-2950 Random + * 3710-3740 NewD + * 4040-4080 DoesYequalX + * 4090-4110 PrintIfNPositive + * 4640-4850 TestPartialUnderflow + * +*/ + +#include +#include + +/* + * To compile this on host using only libm from newlib (and using host libc) + * do: + * gcc -g -DNEED_REENT -DCYGNUS paranoia.c .../newlib-1.6/newlib/libm.a + */ + +#ifdef NEED_REENT +#include +struct _reent libm_reent = _REENT_INIT(libm_reent); +struct _reent *_impure_ptr = &libm_reent; +#endif + +#ifndef NOSIGNAL +#include +#include +#else /* NOSIGNAL */ +#define longjmp(e,v) +#define setjmp(e) 0 +#define jmp_buf int +#endif /* NOSIGNAL */ + +#ifdef SINGLE_PRECISION +#define FLOAT float +#define FABS(x) (float)fabs((double)(x)) +#define FLOOR(x) (float)floor((double)(x)) +#define LOG(x) (float)log((double)(x)) +#define POW(x,y) (float)pow((double)(x),(double)(y)) +#define SQRT(x) (float)sqrt((double)(x)) +#else /* !SINGLE_PRECISION */ +#define FLOAT double +#define FABS(x) fabs(x) +#define FLOOR(x) floor(x) +#define LOG(x) log(x) +#define POW(x,y) pow(x,y) +#define SQRT(x) sqrt(x) +#endif /* SINGLE_PRECISION */ + +jmp_buf ovfl_buf; +extern double fabs (), floor (), log (), pow (), sqrt (); +extern void exit (); +typedef void (*Sig_type) (); +FLOAT Sign (), Random (); +extern void BadCond (); +extern void SqXMinX (); +extern void TstCond (); +extern void notify (); +extern int read (); +extern void Characteristics (); +extern void Heading (); +extern void History (); +extern void Instructions (); +extern void IsYeqX (); +extern void NewD (); +extern void Pause (); +extern void PrintIfNPositive (); +extern void SR3750 (); +extern void SR3980 (); +extern void TstPtUf (); + +Sig_type sigsave; + +#define KEYBOARD 0 + +FLOAT Radix, BInvrse, RadixD2, BMinusU2; + +/*Small floating point constants.*/ +FLOAT Zero = 0.0; +FLOAT Half = 0.5; +FLOAT One = 1.0; +FLOAT Two = 2.0; +FLOAT Three = 3.0; +FLOAT Four = 4.0; +FLOAT Five = 5.0; +FLOAT Eight = 8.0; +FLOAT Nine = 9.0; +FLOAT TwentySeven = 27.0; +FLOAT ThirtyTwo = 32.0; +FLOAT TwoForty = 240.0; +FLOAT MinusOne = -1.0; +FLOAT OneAndHalf = 1.5; + +/*Integer constants*/ +int NoTrials = 20; /*Number of tests for commutativity. */ +#define False 0 +#define True 1 + +/* + * Definitions for declared types + * Guard == (Yes, No); + * Rounding == (Chopped, Rounded, Other); + * Message == packed array [1..40] of char; + * Class == (Flaw, Defect, Serious, Failure); + */ +#define Yes 1 +#define No 0 +#define Chopped 2 +#define Rounded 1 +#define Other 0 +#define Flaw 3 +#define Defect 2 +#define Serious 1 +#define Failure 0 +typedef int Guard, Rounding, Class; +typedef char Message; + +/* Declarations of Variables */ +int Indx; +char ch[8]; +FLOAT AInvrse, A1; +FLOAT C, CInvrse; +FLOAT D, FourD; +FLOAT E0, E1, Exp2, E3, MinSqEr; +FLOAT SqEr, MaxSqEr, E9; +FLOAT Third; +FLOAT F6, F9; +FLOAT H, HInvrse; +int I; +FLOAT StickyBit, J; +FLOAT MyZero; +FLOAT Precision; +FLOAT Q, Q9; +FLOAT R, Random9; +FLOAT T, Underflow, S; +FLOAT OneUlp, UfThold, U1, U2; +FLOAT V, V0, V9; +FLOAT W; +FLOAT X, X1, X2, X8, Random1; +FLOAT Y, Y1, Y2, Random2; +FLOAT Z, PseudoZero, Z1, Z2, Z9; +int ErrCnt[4]; +int fpecount; +int Milestone; +int PageNo; +int M, N, N1; +Guard GMult, GDiv, GAddSub; +Rounding RMult, RDiv, RAddSub, RSqrt; +int Break, Done, NotMonot, Monot, Anomaly, IEEE, SqRWrng, UfNGrad; + +/* Computed constants. + * U1 gap below 1.0, i.e, 1.0 - U1 is next number below 1.0 + * U2 gap above 1.0, i.e, 1.0 + U2 is next number above 1.0 + */ + +int batchmode; /* global batchmode test */ + +/* program name and version variables and macro */ +char *temp; +char *program_name; +char *program_vers; + +#ifndef VERSION +#define VERSION "1.1 [cygnus]" +#endif /* VERSION */ + +#define basename(cp) ((temp=(char *)strrchr((cp), '/')) ? temp+1 : (cp)) + +#ifndef BATCHMODE +# ifdef CYGNUS +# define BATCHMODE +# endif +#endif + +/* floating point exception receiver */ +void +_sigfpe (x) +int x; +{ + fpecount++; + printf ("\n* * * FLOATING-POINT ERROR %d * * *\n", x); + fflush (stdout); + if (sigsave) { +#ifndef NOSIGNAL + signal (SIGFPE, sigsave); +#endif /* NOSIGNAL */ + sigsave = 0; + longjmp (ovfl_buf, 1); + } + exit (1); +} + +#ifdef NOMAIN +#define main paranoia +#endif + +int +main (argc, argv) +int argc; +char **argv; +{ + /* First two assignments use integer right-hand sides. */ + Zero = 0; + One = 1; + Two = One + One; + Three = Two + One; + Four = Three + One; + Five = Four + One; + Eight = Four + Four; + Nine = Three * Three; + TwentySeven = Nine * Three; + ThirtyTwo = Four * Eight; + TwoForty = Four * Five * Three * Four; + MinusOne = -One; + Half = One / Two; + OneAndHalf = One + Half; + ErrCnt[Failure] = 0; + ErrCnt[Serious] = 0; + ErrCnt[Defect] = 0; + ErrCnt[Flaw] = 0; + PageNo = 1; + +#ifdef BATCHMODE + batchmode = 1; /* run test in batchmode? */ +#else /* !BATCHMODE */ + batchmode = 0; /* run test interactively */ +#endif /* BATCHMODE */ + +/* + program_name = basename (argv[0]); +*/ + program_vers = VERSION; + + printf ("%s version %s\n", "Paranoia", program_vers); + + /*=============================================*/ + Milestone = 0; + /*=============================================*/ +#ifndef NOSIGNAL + signal (SIGFPE, _sigfpe); +#endif + + if (!batchmode) { + Instructions (); + Pause (); + Heading (); + Instructions (); + Pause (); + Heading (); + Pause (); + Characteristics (); + Pause (); + History (); + Pause (); + } + + /*=============================================*/ + Milestone = 7; + /*=============================================*/ + printf ("Program is now RUNNING tests on small integers:\n"); + TstCond (Failure, (Zero + Zero == Zero) && (One - One == Zero) + && (One > Zero) && (One + One == Two), + "0+0 != 0, 1-1 != 0, 1 <= 0, or 1+1 != 2"); + Z = -Zero; + if (Z != 0.0) { + ErrCnt[Failure] = ErrCnt[Failure] + 1; + printf ("Comparison alleges that -0.0 is Non-zero!\n"); + U1 = 0.001; + Radix = 1; + TstPtUf (); + } + TstCond (Failure, (Three == Two + One) && (Four == Three + One) + && (Four + Two * (-Two) == Zero) + && (Four - Three - One == Zero), + "3 != 2+1, 4 != 3+1, 4+2*(-2) != 0, or 4-3-1 != 0"); + TstCond (Failure, (MinusOne == (0 - One)) + && (MinusOne + One == Zero) && (One + MinusOne == Zero) + && (MinusOne + FABS (One) == Zero) + && (MinusOne + MinusOne * MinusOne == Zero), + "-1+1 != 0, (-1)+abs(1) != 0, or -1+(-1)*(-1) != 0"); + TstCond (Failure, Half + MinusOne + Half == Zero, + "1/2 + (-1) + 1/2 != 0"); + /*=============================================*/ + Milestone = 10; + /*=============================================*/ + TstCond (Failure, (Nine == Three * Three) + && (TwentySeven == Nine * Three) && (Eight == Four + Four) + && (ThirtyTwo == Eight * Four) + && (ThirtyTwo - TwentySeven - Four - One == Zero), + "9 != 3*3, 27 != 9*3, 32 != 8*4, or 32-27-4-1 != 0"); + TstCond (Failure, (Five == Four + One) && + (TwoForty == Four * Five * Three * Four) + && (TwoForty / Three - Four * Four * Five == Zero) + && (TwoForty / Four - Five * Three * Four == Zero) + && (TwoForty / Five - Four * Three * Four == Zero), + "5 != 4+1, 240/3 != 80, 240/4 != 60, or 240/5 != 48"); + if (ErrCnt[Failure] == 0) { + printf ("-1, 0, 1/2, 1, 2, 3, 4, 5, 9, 27, 32 & 240 are O.K.\n"); + printf ("\n"); + } + printf ("Searching for Radix and Precision.\n"); + W = One; + do { + W = W + W; + Y = W + One; + Z = Y - W; + Y = Z - One; + } + while (MinusOne + FABS (Y) < Zero); + /*.. now W is just big enough that |((W+1)-W)-1| >= 1 ...*/ + Precision = Zero; + Y = One; + do { + Radix = W + Y; + Y = Y + Y; + Radix = Radix - W; + } + while (Radix == Zero); + if (Radix < Two) + Radix = One; + printf ("Radix = %f .\n", Radix); + if (Radix != 1) { + W = One; + do { + Precision = Precision + One; + W = W * Radix; + Y = W + One; + } + while ((Y - W) == One); + } + /*... now W == Radix^Precision is barely too big to satisfy (W+1)-W == 1 + ...*/ + U1 = One / W; + U2 = Radix * U1; + printf ("Closest relative separation found is U1 = %.7e .\n\n", U1); + printf ("Recalculating radix and precision\n "); + + /*save old values*/ + E0 = Radix; + E1 = U1; + E9 = U2; + E3 = Precision; + + X = Four / Three; + Third = X - One; + F6 = Half - Third; + X = F6 + F6; + X = FABS (X - Third); + if (X < U2) + X = U2; + + /*... now X = (unknown no.) ulps of 1+...*/ + do { + U2 = X; + Y = Half * U2 + ThirtyTwo * U2 * U2; + Y = One + Y; + X = Y - One; + } + while (!((U2 <= X) || (X <= Zero))); + + /*... now U2 == 1 ulp of 1 + ... */ + X = Two / Three; + F6 = X - Half; + Third = F6 + F6; + X = Third - Half; + X = FABS (X + F6); + if (X < U1) + X = U1; + + /*... now X == (unknown no.) ulps of 1 -... */ + do { + U1 = X; + Y = Half * U1 + ThirtyTwo * U1 * U1; + Y = Half - Y; + X = Half + Y; + Y = Half - X; + X = Half + Y; + } + while (!((U1 <= X) || (X <= Zero))); + /*... now U1 == 1 ulp of 1 - ... */ + if (U1 == E1) + printf ("confirms closest relative separation U1 .\n"); + else + printf ("gets better closest relative separation U1 = %.7e .\n", U1); + W = One / U1; + F9 = (Half - U1) + Half; + Radix = FLOOR (0.01 + U2 / U1); + if (Radix == E0) + printf ("Radix confirmed.\n"); + else + printf ("MYSTERY: recalculated Radix = %.7e .\n", Radix); + TstCond (Defect, Radix <= Eight + Eight, + "Radix is too big: roundoff problems"); + TstCond (Flaw, (Radix == Two) || (Radix == 10) + || (Radix == One), "Radix is not as good as 2 or 10"); + /*=============================================*/ + Milestone = 20; + /*=============================================*/ + TstCond (Failure, F9 - Half < Half, + "(1-U1)-1/2 < 1/2 is FALSE, prog. fails?"); + X = F9; + I = 1; + Y = X - Half; + Z = Y - Half; + TstCond (Failure, (X != One) + || (Z == Zero), "Comparison is fuzzy,X=1 but X-1/2-1/2 != 0"); + X = One + U2; + I = 0; + /*=============================================*/ + Milestone = 25; + /*=============================================*/ + /*... BMinusU2 = nextafter(Radix, 0) */ + BMinusU2 = Radix - One; + BMinusU2 = (BMinusU2 - U2) + One; + /* Purify Integers */ + if (Radix != One) { + X = -TwoForty * LOG (U1) / LOG (Radix); + Y = FLOOR (Half + X); + if (FABS (X - Y) * Four < One) + X = Y; + Precision = X / TwoForty; + Y = FLOOR (Half + Precision); + if (FABS (Precision - Y) * TwoForty < Half) + Precision = Y; + } + if ((Precision != FLOOR (Precision)) || (Radix == One)) { + printf ("Precision cannot be characterized by an Integer number\n"); + printf ("of significant digits but, by itself, this is a minor flaw.\n"); + } + if (Radix == One) + printf ("logarithmic encoding has precision characterized solely by U1.\n"); + else + printf ("The number of significant digits of the Radix is %f .\n", + Precision); + TstCond (Serious, U2 * Nine * Nine * TwoForty < One, + "Precision worse than 5 decimal figures "); + /*=============================================*/ + Milestone = 30; + /*=============================================*/ + /* Test for extra-precise subepressions */ + X = FABS (((Four / Three - One) - One / Four) * Three - One / Four); + do { + Z2 = X; + X = (One + (Half * Z2 + ThirtyTwo * Z2 * Z2)) - One; + } + while (!((Z2 <= X) || (X <= Zero))); + X = Y = Z = FABS ((Three / Four - Two / Three) * Three - One / Four); + do { + Z1 = Z; + Z = (One / Two - ((One / Two - (Half * Z1 + ThirtyTwo * Z1 * Z1)) + + One / Two)) + One / Two; + } + while (!((Z1 <= Z) || (Z <= Zero))); + do { + do { + Y1 = Y; + Y = (Half - ((Half - (Half * Y1 + ThirtyTwo * Y1 * Y1)) + Half + )) + Half; + } + while (!((Y1 <= Y) || (Y <= Zero))); + X1 = X; + X = ((Half * X1 + ThirtyTwo * X1 * X1) - F9) + F9; + } + while (!((X1 <= X) || (X <= Zero))); + if ((X1 != Y1) || (X1 != Z1)) { + BadCond (Serious, "Disagreements among the values X1, Y1, Z1,\n"); + printf ("respectively %.7e, %.7e, %.7e,\n", X1, Y1, Z1); + printf ("are symptoms of inconsistencies introduced\n"); + printf ("by extra-precise evaluation of arithmetic subexpressions.\n"); + notify ("Possibly some part of this"); + if ((X1 == U1) || (Y1 == U1) || (Z1 == U1)) + printf ( + "That feature is not tested further by this program.\n"); + } else { + if ((Z1 != U1) || (Z2 != U2)) { + if ((Z1 >= U1) || (Z2 >= U2)) { + BadCond (Failure, ""); + notify ("Precision"); + printf ("\tU1 = %.7e, Z1 - U1 = %.7e\n", U1, Z1 - U1); + printf ("\tU2 = %.7e, Z2 - U2 = %.7e\n", U2, Z2 - U2); + } else { + if ((Z1 <= Zero) || (Z2 <= Zero)) { + printf ("Because of unusual Radix = %f", Radix); + printf (", or exact rational arithmetic a result\n"); + printf ("Z1 = %.7e, or Z2 = %.7e ", Z1, Z2); + notify ("of an\nextra-precision"); + } + if (Z1 != Z2 || Z1 > Zero) { + X = Z1 / U1; + Y = Z2 / U2; + if (Y > X) + X = Y; + Q = -LOG (X); + printf ("Some subexpressions appear to be calculated extra\n"); + printf ("precisely with about %g extra B-digits, i.e.\n", + (Q / LOG (Radix))); + printf ("roughly %g extra significant decimals.\n", + Q / LOG (10.)); + } + printf ("That feature is not tested further by this program.\n"); + } + } + } + Pause (); + /*=============================================*/ + Milestone = 35; + /*=============================================*/ + if (Radix >= Two) { + X = W / (Radix * Radix); + Y = X + One; + Z = Y - X; + T = Z + U2; + X = T - Z; + TstCond (Failure, X == U2, + "Subtraction is not normalized X=Y,X+Z != Y+Z!"); + if (X == U2) + printf ( + "Subtraction appears to be normalized, as it should be."); + } + printf ("\nChecking for guard digit in *, /, and -.\n"); + Y = F9 * One; + Z = One * F9; + X = F9 - Half; + Y = (Y - Half) - X; + Z = (Z - Half) - X; + X = One + U2; + T = X * Radix; + R = Radix * X; + X = T - Radix; + X = X - Radix * U2; + T = R - Radix; + T = T - Radix * U2; + X = X * (Radix - One); + T = T * (Radix - One); + if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T == Zero)) + GMult = Yes; + else { + GMult = No; + TstCond (Serious, False, + "* lacks a Guard Digit, so 1*X != X"); + } + Z = Radix * U2; + X = One + Z; + Y = FABS ((X + Z) - X * X) - U2; + X = One - U2; + Z = FABS ((X - U2) - X * X) - U1; + TstCond (Failure, (Y <= Zero) + && (Z <= Zero), "* gets too many final digits wrong.\n"); + Y = One - U2; + X = One + U2; + Z = One / Y; + Y = Z - X; + X = One / Three; + Z = Three / Nine; + X = X - Z; + T = Nine / TwentySeven; + Z = Z - T; + TstCond (Defect, X == Zero && Y == Zero && Z == Zero, + "Division lacks a Guard Digit, so error can exceed 1 ulp\n\ +or 1/3 and 3/9 and 9/27 may disagree"); + Y = F9 / One; + X = F9 - Half; + Y = (Y - Half) - X; + X = One + U2; + T = X / One; + X = T - X; + if ((X == Zero) && (Y == Zero) && (Z == Zero)) + GDiv = Yes; + else { + GDiv = No; + TstCond (Serious, False, + "Division lacks a Guard Digit, so X/1 != X"); + } + X = One / (One + U2); + Y = X - Half - Half; + TstCond (Serious, Y < Zero, + "Computed value of 1/1.000..1 >= 1"); + X = One - U2; + Y = One + Radix * U2; + Z = X * Radix; + T = Y * Radix; + R = Z / Radix; + StickyBit = T / Radix; + X = R - X; + Y = StickyBit - Y; + TstCond (Failure, X == Zero && Y == Zero, + "* and/or / gets too many last digits wrong"); + Y = One - U1; + X = One - F9; + Y = One - Y; + T = Radix - U2; + Z = Radix - BMinusU2; + T = Radix - T; + if ((X == U1) && (Y == U1) && (Z == U2) && (T == U2)) + GAddSub = Yes; + else { + GAddSub = No; + TstCond (Serious, False, + "- lacks Guard Digit, so cancellation is obscured"); + } + if (F9 != One && F9 - One >= Zero) { + BadCond (Serious, "comparison alleges (1-U1) < 1 although\n"); + printf (" subtraction yields (1-U1) - 1 = 0 , thereby vitiating\n"); + printf (" such precautions against division by zero as\n"); + printf (" ... if (X == 1.0) {.....} else {.../(X-1.0)...}\n"); + } + if (GMult == Yes && GDiv == Yes && GAddSub == Yes) + printf ( + " *, /, and - appear to have guard digits, as they should.\n"); + /*=============================================*/ + Milestone = 40; + /*=============================================*/ + Pause (); + printf ("Checking rounding on multiply, divide and add/subtract.\n"); + RMult = Other; + RDiv = Other; + RAddSub = Other; + RadixD2 = Radix / Two; + A1 = Two; + Done = False; + do { + AInvrse = Radix; + do { + X = AInvrse; + AInvrse = AInvrse / A1; + } + while (!(FLOOR (AInvrse) != AInvrse)); + Done = (X == One) || (A1 > Three); + if (!Done) + A1 = Nine + One; + } + while (!(Done)); + if (X == One) + A1 = Radix; + AInvrse = One / A1; + X = A1; + Y = AInvrse; + Done = False; + do { + Z = X * Y - Half; + TstCond (Failure, Z == Half, + "X * (1/X) differs from 1"); + Done = X == Radix; + X = Radix; + Y = One / X; + } + while (!(Done)); + Y2 = One + U2; + Y1 = One - U2; + X = OneAndHalf - U2; + Y = OneAndHalf + U2; + Z = (X - U2) * Y2; + T = Y * Y1; + Z = Z - X; + T = T - X; + X = X * Y2; + Y = (Y + U2) * Y1; + X = X - OneAndHalf; + Y = Y - OneAndHalf; + if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T <= Zero)) { + X = (OneAndHalf + U2) * Y2; + Y = OneAndHalf - U2 - U2; + Z = OneAndHalf + U2 + U2; + T = (OneAndHalf - U2) * Y1; + X = X - (Z + U2); + StickyBit = Y * Y1; + S = Z * Y2; + T = T - Y; + Y = (U2 - Y) + StickyBit; + Z = S - (Z + U2 + U2); + StickyBit = (Y2 + U2) * Y1; + Y1 = Y2 * Y1; + StickyBit = StickyBit - Y2; + Y1 = Y1 - Half; + if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T == Zero) + && (StickyBit == Zero) && (Y1 == Half)) { + RMult = Rounded; + printf ("Multiplication appears to round correctly.\n"); + } else if ((X + U2 == Zero) && (Y < Zero) && (Z + U2 == Zero) + && (T < Zero) && (StickyBit + U2 == Zero) + && (Y1 < Half)) { + RMult = Chopped; + printf ("Multiplication appears to chop.\n"); + } else + printf ("* is neither chopped nor correctly rounded.\n"); + if ((RMult == Rounded) && (GMult == No)) + notify ("Multiplication"); + } else + printf ("* is neither chopped nor correctly rounded.\n"); + /*=============================================*/ + Milestone = 45; + /*=============================================*/ + Y2 = One + U2; + Y1 = One - U2; + Z = OneAndHalf + U2 + U2; + X = Z / Y2; + T = OneAndHalf - U2 - U2; + Y = (T - U2) / Y1; + Z = (Z + U2) / Y2; + X = X - OneAndHalf; + Y = Y - T; + T = T / Y1; + Z = Z - (OneAndHalf + U2); + T = (U2 - OneAndHalf) + T; + if (!((X > Zero) || (Y > Zero) || (Z > Zero) || (T > Zero))) { + X = OneAndHalf / Y2; + Y = OneAndHalf - U2; + Z = OneAndHalf + U2; + X = X - Y; + T = OneAndHalf / Y1; + Y = Y / Y1; + T = T - (Z + U2); + Y = Y - Z; + Z = Z / Y2; + Y1 = (Y2 + U2) / Y2; + Z = Z - OneAndHalf; + Y2 = Y1 - Y2; + Y1 = (F9 - U1) / F9; + if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T == Zero) + && (Y2 == Zero) && (Y2 == Zero) + && (Y1 - Half == F9 - Half)) { + RDiv = Rounded; + printf ("Division appears to round correctly.\n"); + if (GDiv == No) + notify ("Division"); + } else if ((X < Zero) && (Y < Zero) && (Z < Zero) && (T < Zero) + && (Y2 < Zero) && (Y1 - Half < F9 - Half)) { + RDiv = Chopped; + printf ("Division appears to chop.\n"); + } + } + if (RDiv == Other) + printf ("/ is neither chopped nor correctly rounded.\n"); + BInvrse = One / Radix; + TstCond (Failure, (BInvrse * Radix - Half == Half), + "Radix * ( 1 / Radix ) differs from 1"); + /*=============================================*/ + Milestone = 50; + /*=============================================*/ + TstCond (Failure, ((F9 + U1) - Half == Half) + && ((BMinusU2 + U2) - One == Radix - One), + "Incomplete carry-propagation in Addition"); + X = One - U1 * U1; + Y = One + U2 * (One - U2); + Z = F9 - Half; + X = (X - Half) - Z; + Y = Y - One; + if ((X == Zero) && (Y == Zero)) { + RAddSub = Chopped; + printf ("Add/Subtract appears to be chopped.\n"); + } + if (GAddSub == Yes) { + X = (Half + U2) * U2; + Y = (Half - U2) * U2; + X = One + X; + Y = One + Y; + X = (One + U2) - X; + Y = One - Y; + if ((X == Zero) && (Y == Zero)) { + X = (Half + U2) * U1; + Y = (Half - U2) * U1; + X = One - X; + Y = One - Y; + X = F9 - X; + Y = One - Y; + if ((X == Zero) && (Y == Zero)) { + RAddSub = Rounded; + printf ("Addition/Subtraction appears to round correctly.\n"); + if (GAddSub == No) + notify ("Add/Subtract"); + } else + printf ("Addition/Subtraction neither rounds nor chops.\n"); + } else + printf ("Addition/Subtraction neither rounds nor chops.\n"); + } else + printf ("Addition/Subtraction neither rounds nor chops.\n"); + S = One; + X = One + Half * (One + Half); + Y = (One + U2) * Half; + Z = X - Y; + T = Y - X; + StickyBit = Z + T; + if (StickyBit != Zero) { + S = Zero; + BadCond (Flaw, "(X - Y) + (Y - X) is non zero!\n"); + } + StickyBit = Zero; + if ((GMult == Yes) && (GDiv == Yes) && (GAddSub == Yes) + && (RMult == Rounded) && (RDiv == Rounded) + && (RAddSub == Rounded) && (FLOOR (RadixD2) == RadixD2)) { + printf ("Checking for sticky bit.\n"); + X = (Half + U1) * U2; + Y = Half * U2; + Z = One + Y; + T = One + X; + if ((Z - One <= Zero) && (T - One >= U2)) { + Z = T + Y; + Y = Z - X; + if ((Z - T >= U2) && (Y - T == Zero)) { + X = (Half + U1) * U1; + Y = Half * U1; + Z = One - Y; + T = One - X; + if ((Z - One == Zero) && (T - F9 == Zero)) { + Z = (Half - U1) * U1; + T = F9 - Z; + Q = F9 - Y; + if ((T - F9 == Zero) && (F9 - U1 - Q == Zero)) { + Z = (One + U2) * OneAndHalf; + T = (OneAndHalf + U2) - Z + U2; + X = One + Half / Radix; + Y = One + Radix * U2; + Z = X * Y; + if (T == Zero && X + Radix * U2 - Z == Zero) { + if (Radix != Two) { + X = Two + U2; + Y = X / Two; + if ((Y - One == Zero)) + StickyBit = S; + } else + StickyBit = S; + } + } + } + } + } + } + if (StickyBit == One) + printf ("Sticky bit apparently used correctly.\n"); + else + printf ("Sticky bit used incorrectly or not at all.\n"); + TstCond (Flaw, !(GMult == No || GDiv == No || GAddSub == No || + RMult == Other || RDiv == Other || RAddSub == Other), + "lack(s) of guard digits or failure(s) to correctly round or chop\n\ +(noted above) count as one flaw in the final tally below"); + /*=============================================*/ + Milestone = 60; + /*=============================================*/ + printf ("\n"); + printf ("Does Multiplication commute? "); + printf ("Testing on %d random pairs.\n", NoTrials); + Random9 = SQRT (3.0); + Random1 = Third; + I = 1; + do { + X = Random (); + Y = Random (); + Z9 = Y * X; + Z = X * Y; + Z9 = Z - Z9; + I = I + 1; + } + while (!((I > NoTrials) || (Z9 != Zero))); + if (I == NoTrials) { + Random1 = One + Half / Three; + Random2 = (U2 + U1) + One; + Z = Random1 * Random2; + Y = Random2 * Random1; + Z9 = (One + Half / Three) * ((U2 + U1) + One) - (One + Half / + Three) * ((U2 + U1) + One); + } + if (!((I == NoTrials) || (Z9 == Zero))) + BadCond (Defect, "X * Y == Y * X trial fails.\n"); + else + printf (" No failures found in %d integer pairs.\n", NoTrials); + /*=============================================*/ + Milestone = 70; + /*=============================================*/ + printf ("\nRunning test of square root(x).\n"); + TstCond (Failure, (Zero == SQRT (Zero)) + && (-Zero == SQRT (-Zero)) + && (One == SQRT (One)), "Square root of 0.0, -0.0 or 1.0 wrong"); + MinSqEr = Zero; + MaxSqEr = Zero; + J = Zero; + X = Radix; + OneUlp = U2; + SqXMinX (Serious); + X = BInvrse; + OneUlp = BInvrse * U1; + SqXMinX (Serious); + X = U1; + OneUlp = U1 * U1; + SqXMinX (Serious); + if (J != Zero) + Pause (); + printf ("Testing if sqrt(X * X) == X for %d Integers X.\n", NoTrials); + J = Zero; + X = Two; + Y = Radix; + if ((Radix != One)) + do { + X = Y; + Y = Radix * Y; + } + while (!((Y - X >= NoTrials))); + OneUlp = X * U2; + I = 1; + while (I <= NoTrials) { + X = X + One; + SqXMinX (Defect); + if (J > Zero) + break; + I = I + 1; + } + printf ("Test for sqrt monotonicity.\n"); + I = -1; + X = BMinusU2; + Y = Radix; + Z = Radix + Radix * U2; + NotMonot = False; + Monot = False; + while (!(NotMonot || Monot)) { + I = I + 1; + X = SQRT (X); + Q = SQRT (Y); + Z = SQRT (Z); + if ((X > Q) || (Q > Z)) + NotMonot = True; + else { + Q = FLOOR (Q + Half); + if ((I > 0) || (Radix == Q * Q)) + Monot = True; + else if (I > 0) { + if (I > 1) + Monot = True; + else { + Y = Y * BInvrse; + X = Y - U1; + Z = Y + U1; + } + } else { + Y = Q; + X = Y - U2; + Z = Y + U2; + } + } + } + if (Monot) + printf ("sqrt has passed a test for Monotonicity.\n"); + else { + BadCond (Defect, ""); + printf ("sqrt(X) is non-monotonic for X near %.7e .\n", Y); + } + /*=============================================*/ + Milestone = 80; + /*=============================================*/ + MinSqEr = MinSqEr + Half; + MaxSqEr = MaxSqEr - Half; + Y = (SQRT (One + U2) - One) / U2; + SqEr = (Y - One) + U2 / Eight; + if (SqEr > MaxSqEr) + MaxSqEr = SqEr; + SqEr = Y + U2 / Eight; + if (SqEr < MinSqEr) + MinSqEr = SqEr; + Y = ((SQRT (F9) - U2) - (One - U2)) / U1; + SqEr = Y + U1 / Eight; + if (SqEr > MaxSqEr) + MaxSqEr = SqEr; + SqEr = (Y + One) + U1 / Eight; + if (SqEr < MinSqEr) + MinSqEr = SqEr; + OneUlp = U2; + X = OneUlp; + for (Indx = 1; Indx <= 3; ++Indx) { + Y = SQRT ((X + U1 + X) + F9); + Y = ((Y - U2) - ((One - U2) + X)) / OneUlp; + Z = ((U1 - X) + F9) * Half * X * X / OneUlp; + SqEr = (Y + Half) + Z; + if (SqEr < MinSqEr) + MinSqEr = SqEr; + SqEr = (Y - Half) + Z; + if (SqEr > MaxSqEr) + MaxSqEr = SqEr; + if (((Indx == 1) || (Indx == 3))) + X = OneUlp * Sign (X) * FLOOR (Eight / (Nine * SQRT (OneUlp))); + else { + OneUlp = U1; + X = -OneUlp; + } + } + /*=============================================*/ + Milestone = 85; + /*=============================================*/ + SqRWrng = False; + Anomaly = False; + RSqrt = Other; /* ~dgh */ + if (Radix != One) { + printf ("Testing whether sqrt is rounded or chopped.\n"); + D = FLOOR (Half + POW (Radix, One + Precision - FLOOR (Precision))); + /* ... == Radix^(1 + fract) if (Precision == Integer + fract. */ + X = D / Radix; + Y = D / A1; + if ((X != FLOOR (X)) || (Y != FLOOR (Y))) { + Anomaly = True; + } else { + X = Zero; + Z2 = X; + Y = One; + Y2 = Y; + Z1 = Radix - One; + FourD = Four * D; + do { + if (Y2 > Z2) { + Q = Radix; + Y1 = Y; + do { + X1 = FABS (Q + FLOOR (Half - Q / Y1) * Y1); + Q = Y1; + Y1 = X1; + } + while (!(X1 <= Zero)); + if (Q <= One) { + Z2 = Y2; + Z = Y; + } + } + Y = Y + Two; + X = X + Eight; + Y2 = Y2 + X; + if (Y2 >= FourD) + Y2 = Y2 - FourD; + } + while (!(Y >= D)); + X8 = FourD - Z2; + Q = (X8 + Z * Z) / FourD; + X8 = X8 / Eight; + if (Q != FLOOR (Q)) + Anomaly = True; + else { + Break = False; + do { + X = Z1 * Z; + X = X - FLOOR (X / Radix) * Radix; + if (X == One) + Break = True; + else + Z1 = Z1 - One; + } + while (!(Break || (Z1 <= Zero))); + if ((Z1 <= Zero) && (!Break)) + Anomaly = True; + else { + if (Z1 > RadixD2) + Z1 = Z1 - Radix; + do { + NewD (); + } + while (!(U2 * D >= F9)); + if (D * Radix - D != W - D) + Anomaly = True; + else { + Z2 = D; + I = 0; + Y = D + (One + Z) * Half; + X = D + Z + Q; + SR3750 (); + Y = D + (One - Z) * Half + D; + X = D - Z + D; + X = X + Q + X; + SR3750 (); + NewD (); + if (D - Z2 != W - Z2) + Anomaly = True; + else { + Y = (D - Z2) + (Z2 + (One - Z) * Half); + X = (D - Z2) + (Z2 - Z + Q); + SR3750 (); + Y = (One + Z) * Half; + X = Q; + SR3750 (); + if (I == 0) + Anomaly = True; + } + } + } + } + } + if ((I == 0) || Anomaly) { + BadCond (Failure, "Anomalous arithmetic with Integer < "); + printf ("Radix^Precision = %.7e\n", W); + printf (" fails test whether sqrt rounds or chops.\n"); + SqRWrng = True; + } + } + if (!Anomaly) { + if (!((MinSqEr < Zero) || (MaxSqEr > Zero))) { + RSqrt = Rounded; + printf ("Square root appears to be correctly rounded.\n"); + } else { + if ((MaxSqEr + U2 > U2 - Half) || (MinSqEr > Half) + || (MinSqEr + Radix < Half)) + SqRWrng = True; + else { + RSqrt = Chopped; + printf ("Square root appears to be chopped.\n"); + } + } + } + if (SqRWrng) { + printf ("Square root is neither chopped nor correctly rounded.\n"); + printf ("Observed errors run from %.7e ", MinSqEr - Half); + printf ("to %.7e ulps.\n", Half + MaxSqEr); + TstCond (Serious, MaxSqEr - MinSqEr < Radix * Radix, + "sqrt gets too many last digits wrong"); + } + /*=============================================*/ + Milestone = 90; + /*=============================================*/ + Pause (); + printf ("Testing powers Z^i for small Integers Z and i.\n"); + N = 0; + /* ... test powers of zero. */ + I = 0; + Z = -Zero; + M = 3; + Break = False; + do { + X = One; + SR3980 (); + if (I <= 10) { + I = 1023; + SR3980 (); + } + if (Z == MinusOne) + Break = True; + else { + Z = MinusOne; + /* .. if(-1)^N is invalid, replace MinusOne by One. */ + I = -4; + } + } + while (!Break); + PrintIfNPositive (); + N1 = N; + N = 0; + Z = A1; + M = (int) FLOOR (Two * LOG (W) / LOG (A1)); + Break = False; + do { + X = Z; + I = 1; + SR3980 (); + if (Z == AInvrse) + Break = True; + else + Z = AInvrse; + } + while (!(Break)); + /*=============================================*/ + Milestone = 100; + /*=============================================*/ + /* Powers of Radix have been tested, */ + /* next try a few primes */ + M = NoTrials; + Z = Three; + do { + X = Z; + I = 1; + SR3980 (); + do { + Z = Z + Two; + } + while (Three * FLOOR (Z / Three) == Z); + } + while (Z < Eight * Three); + if (N > 0) { + printf ("Errors like this may invalidate financial calculations\n"); + printf ("\tinvolving interest rates.\n"); + } + PrintIfNPositive (); + N += N1; + if (N == 0) + printf ("... no discrepancies found.\n"); + if (N > 0) + Pause (); + else + printf ("\n"); + /*=============================================*/ + Milestone = 110; + /*=============================================*/ + printf ("Seeking Underflow thresholds UfThold and E0.\n"); + D = U1; + if (Precision != FLOOR (Precision)) { + D = BInvrse; + X = Precision; + do { + D = D * BInvrse; + X = X - One; + } + while (X > Zero); + } + Y = One; + Z = D; + /* ... D is power of 1/Radix < 1. */ + do { + C = Y; + Y = Z; + Z = Y * Y; + } + while ((Y > Z) && (Z + Z > Z)); + Y = C; + Z = Y * D; + do { + C = Y; + Y = Z; + Z = Y * D; + } + while ((Y > Z) && (Z + Z > Z)); + if (Radix < Two) + HInvrse = Two; + else + HInvrse = Radix; + H = One / HInvrse; + /* ... 1/HInvrse == H == Min(1/Radix, 1/2) */ + CInvrse = One / C; + E0 = C; + Z = E0 * H; + /* ...1/Radix^(BIG Integer) << 1 << CInvrse == 1/C */ + do { + Y = E0; + E0 = Z; + Z = E0 * H; + } + while ((E0 > Z) && (Z + Z > Z)); + UfThold = E0; + E1 = Zero; + Q = Zero; + E9 = U2; + S = One + E9; + D = C * S; + if (D <= C) { + E9 = Radix * U2; + S = One + E9; + D = C * S; + if (D <= C) { + BadCond (Failure, "multiplication gets too many last digits wrong.\n"); + Underflow = E0; + Y1 = Zero; + PseudoZero = Z; + Pause (); + } + } else { + Underflow = D; + PseudoZero = Underflow * H; + UfThold = Zero; + do { + Y1 = Underflow; + Underflow = PseudoZero; + if (E1 + E1 <= E1) { + Y2 = Underflow * HInvrse; + E1 = FABS (Y1 - Y2); + Q = Y1; + if ((UfThold == Zero) && (Y1 != Y2)) + UfThold = Y1; + } + PseudoZero = PseudoZero * H; + } + while ((Underflow > PseudoZero) + && (PseudoZero + PseudoZero > PseudoZero)); + } + /* Comment line 4530 .. 4560 */ + if (PseudoZero != Zero) { + printf ("\n"); + Z = PseudoZero; + /* ... Test PseudoZero for "phoney- zero" violates */ + /* ... PseudoZero < Underflow or PseudoZero < PseudoZero + PseudoZero + ... */ + if (PseudoZero <= Zero) { + BadCond (Failure, "Positive expressions can underflow to an\n"); + printf ("allegedly negative value\n"); + printf ("PseudoZero that prints out as: %g .\n", PseudoZero); + X = -PseudoZero; + if (X <= Zero) { + printf ("But -PseudoZero, which should be\n"); + printf ("positive, isn't; it prints out as %g .\n", X); + } + } else { + BadCond (Flaw, "Underflow can stick at an allegedly positive\n"); + printf ("value PseudoZero that prints out as %g .\n", PseudoZero); + } + TstPtUf (); + } + /*=============================================*/ + Milestone = 120; + /*=============================================*/ + if (CInvrse * Y > CInvrse * Y1) { + S = H * S; + E0 = Underflow; + } + if (!((E1 == Zero) || (E1 == E0))) { + BadCond (Defect, ""); + if (E1 < E0) { + printf ("Products underflow at a higher"); + printf (" threshold than differences.\n"); + if (PseudoZero == Zero) + E0 = E1; + } else { + printf ("Difference underflows at a higher"); + printf (" threshold than products.\n"); + } + } + printf ("Smallest strictly positive number found is E0 = %g .\n", E0); + Z = E0; + TstPtUf (); + Underflow = E0; + if (N == 1) + Underflow = Y; + I = 4; + if (E1 == Zero) + I = 3; + if (UfThold == Zero) + I = I - 2; + UfNGrad = True; + switch (I) { + case 1: + UfThold = Underflow; + if ((CInvrse * Q) != ((CInvrse * Y) * S)) { + UfThold = Y; + BadCond (Failure, "Either accuracy deteriorates as numbers\n"); + printf ("approach a threshold = %.17e\n", UfThold);; + printf (" coming down from %.17e\n", C); + printf (" or else multiplication gets too many last digits wrong.\n"); + } + Pause (); + break; + + case 2: + BadCond (Failure, "Underflow confuses Comparison, which alleges that\n"); + printf ("Q == Y while denying that |Q - Y| == 0; these values\n"); + printf ("print out as Q = %.17e, Y = %.17e .\n", Q, Y2); + printf ("|Q - Y| = %.17e .\n", FABS (Q - Y2)); + UfThold = Q; + break; + + case 3: + X = X; + break; + + case 4: + if ((Q == UfThold) && (E1 == E0) + && (FABS (UfThold - E1 / E9) <= E1)) { + UfNGrad = False; + printf ("Underflow is gradual; it incurs Absolute Error =\n"); + printf ("(roundoff in UfThold) < E0.\n"); + Y = E0 * CInvrse; + Y = Y * (OneAndHalf + U2); + X = CInvrse * (One + U2); + Y = Y / X; + IEEE = (Y == E0); + } + } + if (UfNGrad) { + printf ("\n"); + sigsave = _sigfpe; + if (setjmp (ovfl_buf)) { + printf ("Underflow / UfThold failed!\n"); + R = H + H; + } else + R = SQRT (Underflow / UfThold); + sigsave = 0; + if (R <= H) { + Z = R * UfThold; + X = Z * (One + R * H * (One + H)); + } else { + Z = UfThold; + X = Z * (One + H * H * (One + H)); + } + if (!((X == Z) || (X - Z != Zero))) { + BadCond (Flaw, ""); + printf ("X = %.17e\n\tis not equal to Z = %.17e .\n", X, Z); + Z9 = X - Z; + printf ("yet X - Z yields %.17e .\n", Z9); + printf (" Should this NOT signal Underflow, "); + printf ("this is a SERIOUS DEFECT\nthat causes "); + printf ("confusion when innocent statements like\n");; + printf (" if (X == Z) ... else"); + printf (" ... (f(X) - f(Z)) / (X - Z) ...\n"); + printf ("encounter Division by Zero although actually\n"); + sigsave = _sigfpe; + if (setjmp (ovfl_buf)) + printf ("X / Z fails!\n"); + else + printf ("X / Z = 1 + %g .\n", (X / Z - Half) - Half); + sigsave = 0; + } + } + printf ("The Underflow threshold is %.17e, %s\n", UfThold, + " below which"); + printf ("calculation may suffer larger Relative error than "); + printf ("merely roundoff.\n"); + Y2 = U1 * U1; + Y = Y2 * Y2; + Y2 = Y * U1; + if (Y2 <= UfThold) { + if (Y > E0) { + BadCond (Defect, ""); + I = 5; + } else { + BadCond (Serious, ""); + I = 4; + } + printf ("Range is too narrow; U1^%d Underflows.\n", I); + } + /*=============================================*/ + Milestone = 130; + /*=============================================*/ + Y = -FLOOR (Half - TwoForty * LOG (UfThold) / LOG (HInvrse)) / TwoForty; + Y2 = Y + Y; + printf ("Since underflow occurs below the threshold\n"); + printf ("UfThold = (%.17e) ^ (%.17e)\nonly underflow ", HInvrse, Y); + printf ("should afflict the expression\n\t(%.17e) ^ (%.17e);\n", + HInvrse, Y2); + printf ("actually calculating yields:"); + if (setjmp (ovfl_buf)) { + sigsave = 0; + BadCond (Serious, "trap on underflow.\n"); + } else { + sigsave = _sigfpe; + V9 = POW (HInvrse, Y2); + sigsave = 0; + printf (" %.17e .\n", V9); + if (!((V9 >= Zero) && (V9 <= (Radix + Radix + E9) * UfThold))) { + BadCond (Serious, "this is not between 0 and underflow\n"); + printf (" threshold = %.17e .\n", UfThold); + } else if (!(V9 > UfThold * (One + E9))) + printf ("This computed value is O.K.\n"); + else { + BadCond (Defect, "this is not between 0 and underflow\n"); + printf (" threshold = %.17e .\n", UfThold); + } + } + /*=============================================*/ + Milestone = 140; + /*=============================================*/ + printf ("\n"); + /* ...calculate Exp2 == exp(2) == 7.389056099... */ + X = Zero; + I = 2; + Y = Two * Three; + Q = Zero; + N = 0; + do { + Z = X; + I = I + 1; + Y = Y / (I + I); + R = Y + Q; + X = Z + R; + Q = (Z - X) + R; + } + while (X > Z); + Z = (OneAndHalf + One / Eight) + X / (OneAndHalf * ThirtyTwo); + X = Z * Z; + Exp2 = X * X; + X = F9; + Y = X - U1; + printf ("Testing X^((X + 1) / (X - 1)) vs. exp(2) = %.17e as X -> 1.\n", + Exp2); + for (I = 1;;) { + Z = X - BInvrse; + Z = (X + One) / (Z - (One - BInvrse)); + Q = POW (X, Z) - Exp2; + if (FABS (Q) > TwoForty * U2) { + N = 1; + V9 = (X - BInvrse) - (One - BInvrse); + BadCond (Defect, "Calculated"); + printf (" %.17e for\n", POW (X, Z)); + printf ("\t(1 + (%.17e) ^ (%.17e);\n", V9, Z); + printf ("\tdiffers from correct value by %.17e .\n", Q); + printf ("\tThis much error may spoil financial\n"); + printf ("\tcalculations involving tiny interest rates.\n"); + break; + } else { + Z = (Y - X) * Two + Y; + X = Y; + Y = Z; + Z = One + (X - F9) * (X - F9); + if (Z > One && I < NoTrials) + I++; + else { + if (X > One) { + if (N == 0) + printf ("Accuracy seems adequate.\n"); + break; + } else { + X = One + U2; + Y = U2 + U2; + Y += X; + I = 1; + } + } + } + } + /*=============================================*/ + Milestone = 150; + /*=============================================*/ + printf ("Testing powers Z^Q at four nearly extreme values.\n"); + N = 0; + Z = A1; + Q = FLOOR (Half - LOG (C) / LOG (A1)); + Break = False; + do { + X = CInvrse; + Y = POW (Z, Q); + IsYeqX (); + Q = -Q; + X = C; + Y = POW (Z, Q); + IsYeqX (); + if (Z < One) + Break = True; + else + Z = AInvrse; + } + while (!(Break)); + PrintIfNPositive (); + if (N == 0) + printf (" ... no discrepancies found.\n"); + printf ("\n"); + + /*=============================================*/ + Milestone = 160; + /*=============================================*/ + Pause (); + printf ("Searching for Overflow threshold:\n"); + printf ("This may generate an error.\n"); + Y = -CInvrse; + V9 = HInvrse * Y; + sigsave = _sigfpe; + if (setjmp (ovfl_buf)) { + I = 0; + V9 = Y; + goto overflow; + } + do { + V = Y; + Y = V9; + V9 = HInvrse * Y; + } + while (V9 < Y); + I = 1; + overflow: + sigsave = 0; + Z = V9; + printf ("Can `Z = -Y' overflow?\n"); + printf ("Trying it on Y = %.17e .\n", Y); + V9 = -Y; + V0 = V9; + if (V - Y == V + V0) + printf ("Seems O.K.\n"); + else { + printf ("finds a "); + BadCond (Flaw, "-(-Y) differs from Y.\n"); + } + if (Z != Y) { + BadCond (Serious, ""); + printf ("overflow past %.17e\n\tshrinks to %.17e .\n", Y, Z); + } + if (I) { + Y = V * (HInvrse * U2 - HInvrse); + Z = Y + ((One - HInvrse) * U2) * V; + if (Z < V0) + Y = Z; + if (Y < V0) + V = Y; + if (V0 - V < V0) + V = V0; + } else { + V = Y * (HInvrse * U2 - HInvrse); + V = V + ((One - HInvrse) * U2) * Y; + } + printf ("Overflow threshold is V = %.17e .\n", V); + if (I) + printf ("Overflow saturates at V0 = %.17e .\n", V0); + else + printf ("There is no saturation value because \ +the system traps on overflow.\n"); + V9 = V * One; + printf ("No Overflow should be signaled for V * 1 = %.17e\n", V9); + V9 = V / One; + printf (" nor for V / 1 = %.17e .\n", V9); + printf ("Any overflow signal separating this * from the one\n"); + printf ("above is a DEFECT.\n"); + /*=============================================*/ + Milestone = 170; + /*=============================================*/ + if (!(-V < V && -V0 < V0 && -UfThold < V && UfThold < V)) { + BadCond (Failure, "Comparisons involving "); + printf ("+-%g, +-%g\nand +-%g are confused by Overflow.", + V, V0, UfThold); + } + /*=============================================*/ + Milestone = 175; + /*=============================================*/ + printf ("\n"); + for (Indx = 1; Indx <= 3; ++Indx) { + switch (Indx) { + case 1: + Z = UfThold; + break; + case 2: + Z = E0; + break; + case 3: + Z = PseudoZero; + break; + } + if (Z != Zero) { + V9 = SQRT (Z); + Y = V9 * V9; + if (Y / (One - Radix * E9) < Z + || Y > (One + Radix * E9) * Z) { /* dgh: + E9 --> * E9 */ + if (V9 > U1) + BadCond (Serious, ""); + else + BadCond (Defect, ""); + printf ("Comparison alleges that what prints as Z = %.17e\n", Z); + printf (" is too far from sqrt(Z) ^ 2 = %.17e .\n", Y); + } + } + } + /*=============================================*/ + Milestone = 180; + /*=============================================*/ + for (Indx = 1; Indx <= 2; ++Indx) { + if (Indx == 1) + Z = V; + else + Z = V0; + V9 = SQRT (Z); + X = (One - Radix * E9) * V9; + V9 = V9 * X; + if (((V9 < (One - Two * Radix * E9) * Z) || (V9 > Z))) { + Y = V9; + if (X < W) + BadCond (Serious, ""); + else + BadCond (Defect, ""); + printf ("Comparison alleges that Z = %17e\n", Z); + printf (" is too far from sqrt(Z) ^ 2 (%.17e) .\n", Y); + } + } + /*=============================================*/ + Milestone = 190; + /*=============================================*/ + Pause (); + X = UfThold * V; + Y = Radix * Radix; + if (X * Y < One || X > Y) { + if (X * Y < U1 || X > Y / U1) + BadCond (Defect, "Badly"); + else + BadCond (Flaw, ""); + + printf (" unbalanced range; UfThold * V = %.17e\n\t%s\n", + X, "is too far from 1.\n"); + } + /*=============================================*/ + Milestone = 200; + /*=============================================*/ + for (Indx = 1; Indx <= 5; ++Indx) { + X = F9; + switch (Indx) { + case 2: + X = One + U2; + break; + case 3: + X = V; + break; + case 4: + X = UfThold; + break; + case 5: + X = Radix; + } + Y = X; + sigsave = _sigfpe; + if (setjmp (ovfl_buf)) + printf (" X / X traps when X = %g\n", X); + else { + V9 = (Y / X - Half) - Half; + if (V9 == Zero) + continue; + if (V9 == -U1 && Indx < 5) + BadCond (Flaw, ""); + else + BadCond (Serious, ""); + printf (" X / X differs from 1 when X = %.17e\n", X); + printf (" instead, X / X - 1/2 - 1/2 = %.17e .\n", V9); + } + sigsave = 0; + } + /*=============================================*/ + Milestone = 210; + /*=============================================*/ + MyZero = Zero; + printf ("\n"); + printf ("What message and/or values does Division by Zero produce?\n"); +#ifndef BATCHMODE + printf ("This can interupt your program. You can "); + printf ("skip this part if you wish.\n"); + printf ("Do you wish to compute 1 / 0? "); + fflush (stdout); + read (KEYBOARD, ch, 8); + if ((ch[0] == 'Y') || (ch[0] == 'y')) { +#endif /* !BATCHMODE */ + sigsave = _sigfpe; + printf (" Trying to compute 1 / 0 produces ..."); + if (!setjmp (ovfl_buf)) + printf (" %.7e .\n", One / MyZero); + sigsave = 0; +#ifndef BATCHMODE + } else + printf ("O.K.\n"); + printf ("\nDo you wish to compute 0 / 0? "); + fflush (stdout); + read (KEYBOARD, ch, 80); + if ((ch[0] == 'Y') || (ch[0] == 'y')) { +#endif /* !BATCHMODE */ + sigsave = _sigfpe; + printf ("\n Trying to compute 0 / 0 produces ..."); + if (!setjmp (ovfl_buf)) + printf (" %.7e .\n", Zero / MyZero); + sigsave = 0; +#ifndef BATCHMODE + } else + printf ("O.K.\n"); +#endif /* !BATCHMODE */ + /*=============================================*/ + Milestone = 220; + /*=============================================*/ + + Pause (); + printf ("\n"); + { + static char *msg[] = + { + "FAILUREs encountered =", + "SERIOUS DEFECTs discovered =", + "DEFECTs discovered =", + "FLAWs discovered ="}; + int i; + for (i = 0; i < 4; i++) + if (ErrCnt[i]) + printf ("The number of %-29s %d.\n", + msg[i], ErrCnt[i]); + } + + printf ("\n"); + if ((ErrCnt[Failure] + ErrCnt[Serious] + ErrCnt[Defect] + + ErrCnt[Flaw]) > 0) { + if ((ErrCnt[Failure] + ErrCnt[Serious] + ErrCnt[ + Defect] == 0) && (ErrCnt[Flaw] > 0)) { + printf ("The arithmetic diagnosed seems "); + printf ("Satisfactory though flawed.\n"); + } + if ((ErrCnt[Failure] + ErrCnt[Serious] == 0) + && (ErrCnt[Defect] > 0)) { + printf ("The arithmetic diagnosed may be Acceptable\n"); + printf ("despite inconvenient Defects.\n"); + } + if ((ErrCnt[Failure] + ErrCnt[Serious]) > 0) { + printf ("The arithmetic diagnosed has "); + printf ("unacceptable Serious Defects.\n"); + } + if (ErrCnt[Failure] > 0) { + printf ("Potentially fatal FAILURE may have spoiled this"); + printf (" program's subsequent diagnoses.\n"); + } + } else { + + printf ("No failures, defects nor flaws have been discovered.\n"); + if (!((RMult == Rounded) && (RDiv == Rounded) + && (RAddSub == Rounded) && (RSqrt == Rounded))) + printf ("The arithmetic diagnosed seems Satisfactory.\n"); + else { + if (StickyBit >= One && + (Radix - Two) * (Radix - Nine - One) == Zero) { + printf ("Rounding appears to conform to "); + printf ("the proposed IEEE standard P"); + if ((Radix == Two) && + ((Precision - Four * Three * Two) * + (Precision - TwentySeven - + TwentySeven + One) == Zero)) + printf ("754"); + else + printf ("854"); + if (IEEE) + printf (".\n"); + else { + printf (",\nexcept for possibly Double Rounding"); + printf (" during Gradual Underflow.\n"); + } + } + printf ("The arithmetic diagnosed appears to be Excellent!\n"); + } + } + + if (fpecount) + printf ("\nA total of %d floating point exceptions were registered.\n", + fpecount); + printf ("END OF TEST.\n"); + return 0; +} + +FLOAT +Sign (X) + FLOAT X; +{ + return X >= 0. ? 1.0 : -1.0; +} + +void +Pause () +{ +#ifndef BATCHMODE + char ch[8]; + + printf ("\nTo continue, press RETURN"); + fflush (stdout); + read (KEYBOARD, ch, 8); +#endif /* !BATCHMODE */ +#ifndef CYGNUS + printf ("\nDiagnosis resumes after milestone Number %d", Milestone); + printf (" Page: %d\n\n", PageNo); + ++Milestone; + ++PageNo; +#endif /* !CYGNUS */ +} + +void +TstCond (K, Valid, T) + int K, Valid; + char *T; +{ +#ifdef CYGNUS + printf ("TEST: %s\n", T); +#endif /* CYGNUS */ + if (!Valid) { + BadCond (K, T); + printf (".\n"); + } +#ifdef CYGNUS + printf ("PASS: %s\n", T); +#endif /* CYGNUS */ +} + +void +BadCond (K, T) + int K; + char *T; +{ + static char *msg[] = + {"FAILURE", "SERIOUS DEFECT", "DEFECT", "FLAW"}; + + ErrCnt[K] = ErrCnt[K] + 1; +#ifndef CYGNUS + printf ("%s: %s", msg[K], T); +#else + printf ("ERROR: Severity: %s: %s", msg[K], T); +#endif /* CYGNUS */ +} + +/* + * Random computes + * X = (Random1 + Random9)^5 + * Random1 = X - FLOOR(X) + 0.000005 * X; + * and returns the new value of Random1 +*/ +FLOAT +Random () +{ + FLOAT X, Y; + + X = Random1 + Random9; + Y = X * X; + Y = Y * Y; + X = X * Y; + Y = X - FLOOR (X); + Random1 = Y + X * 0.000005; + return (Random1); +} + +void +SqXMinX (ErrKind) + int ErrKind; +{ + FLOAT XA, XB; + + XB = X * BInvrse; + XA = X - XB; + SqEr = ((SQRT (X * X) - XB) - XA) / OneUlp; + if (SqEr != Zero) { + if (SqEr < MinSqEr) + MinSqEr = SqEr; + if (SqEr > MaxSqEr) + MaxSqEr = SqEr; + J = J + 1.0; + BadCond (ErrKind, "\n"); + printf ("sqrt( %.17e) - %.17e = %.17e\n", X * X, X, OneUlp * SqEr); + printf ("\tinstead of correct value 0 .\n"); + } +} + +void +NewD () +{ + X = Z1 * Q; + X = FLOOR (Half - X / Radix) * Radix + X; + Q = (Q - X * Z) / Radix + X * X * (D / Radix); + Z = Z - Two * X * D; + if (Z <= Zero) { + Z = -Z; + Z1 = -Z1; + } + D = Radix * D; +} + +void +SR3750 () +{ + if (!((X - Radix < Z2 - Radix) || (X - Z2 > W - Z2))) { + I = I + 1; + X2 = SQRT (X * D); + Y2 = (X2 - Z2) - (Y - Z2); + X2 = X8 / (Y - Half); + X2 = X2 - Half * X2 * X2; + SqEr = (Y2 + Half) + (Half - X2); + if (SqEr < MinSqEr) + MinSqEr = SqEr; + SqEr = Y2 - X2; + if (SqEr > MaxSqEr) + MaxSqEr = SqEr; + } +} + +void +IsYeqX () +{ + if (Y != X) { + if (N <= 0) { + if (Z == Zero && Q <= Zero) + printf ("WARNING: computing\n"); + else + BadCond (Defect, "computing\n"); + printf ("\t(%.17e) ^ (%.17e)\n", Z, Q); + printf ("\tyielded %.17e;\n", Y); + printf ("\twhich compared unequal to correct %.17e ;\n", + X); + printf ("\t\tthey differ by %.17e .\n", Y - X); + } + N = N + 1; /* ... count discrepancies. */ + } +} + +void +SR3980 () +{ + do { + Q = (FLOAT) I; + Y = POW (Z, Q); + IsYeqX (); + if (++I > M) + break; + X = Z * X; + } + while (X < W); +} + +void +PrintIfNPositive () +{ + if (N > 0) + printf ("Similar discrepancies have occurred %d times.\n", N); +} + +void +TstPtUf () +{ + N = 0; + if (Z != Zero) { + printf ("Since comparison denies Z = 0, evaluating "); + printf ("(Z + Z) / Z should be safe.\n"); + sigsave = _sigfpe; + if (setjmp (ovfl_buf)) + goto very_serious; + Q9 = (Z + Z) / Z; + printf ("What the machine gets for (Z + Z) / Z is %.17e .\n", + Q9); + if (FABS (Q9 - Two) < Radix * U2) { + printf ("This is O.K., provided Over/Underflow"); + printf (" has NOT just been signaled.\n"); + } else { + if ((Q9 < One) || (Q9 > Two)) { + very_serious: + N = 1; + ErrCnt[Serious] = ErrCnt[Serious] + 1; + printf ("This is a VERY SERIOUS DEFECT!\n"); + } else { + N = 1; + ErrCnt[Defect] = ErrCnt[Defect] + 1; + printf ("This is a DEFECT!\n"); + } + } + sigsave = 0; + V9 = Z * One; + Random1 = V9; + V9 = One * Z; + Random2 = V9; + V9 = Z / One; + if ((Z == Random1) && (Z == Random2) && (Z == V9)) { + if (N > 0) + Pause (); + } else { + N = 1; + BadCond (Defect, "What prints as Z = "); + printf ("%.17e\n\tcompares different from ", Z); + if (Z != Random1) + printf ("Z * 1 = %.17e ", Random1); + if (!((Z == Random2) + || (Random2 == Random1))) + printf ("1 * Z == %g\n", Random2); + if (!(Z == V9)) + printf ("Z / 1 = %.17e\n", V9); + if (Random2 != Random1) { + ErrCnt[Defect] = ErrCnt[Defect] + 1; + BadCond (Defect, "Multiplication does not commute!\n"); + printf ("\tComparison alleges that 1 * Z = %.17e\n", + Random2); + printf ("\tdiffers from Z * 1 = %.17e\n", Random1); + } + Pause (); + } + } +} + +void +notify (s) + char *s; +{ + printf ("%s test appears to be inconsistent...\n", s); + printf (" PLEASE NOTIFY KARPINKSI!\n"); +} + +void +msglist (s) + char **s; +{ + while (*s) + printf ("%s\n", *s++); +} + +void +Instructions () +{ + static char *instr[] = + { + "Lest this program stop prematurely, i.e. before displaying\n", + " `END OF TEST',\n", + "try to persuade the computer NOT to terminate execution when an", + "error like Over/Underflow or Division by Zero occurs, but rather", + "to persevere with a surrogate value after, perhaps, displaying some", + "warning. If persuasion avails naught, don't despair but run this", + "program anyway to see how many milestones it passes, and then", + "amend it to make further progress.\n", + "Answer questions with Y, y, N or n (unless otherwise indicated).\n", + 0}; + + msglist (instr); +} + +void +Heading () +{ + static char *head[] = + { + "Users are invited to help debug and augment this program so it will", + "cope with unanticipated and newly uncovered arithmetic pathologies.\n", + "Please send suggestions and interesting results to", + "\tRichard Karpinski", + "\tComputer Center U-76", + "\tUniversity of California", + "\tSan Francisco, CA 94143-0704, USA\n", + "In doing so, please include the following information:", +#ifdef SINGLE_PRECISION + "\tPrecision:\tsingle;", +#else /* !SINGLE_PRECISION */ + "\tPrecision:\tdouble;", +#endif /* SINGLE_PRECISION */ + "\tVersion:\t10 February 1989;", + "\tComputer:\n", + "\tCompiler:\n", + "\tOptimization level:\n", + "\tOther relevant compiler options:", + 0}; + + msglist (head); +} + +void +Characteristics () +{ + static char *chars[] = + { + "Running this program should reveal these characteristics:", + " Radix = 1, 2, 4, 8, 10, 16, 100, 256 ...", + " Precision = number of significant digits carried.", + " U2 = Radix/Radix^Precision = One Ulp", + "\t(OneUlpnit in the Last Place) of 1.000xxx .", + " U1 = 1/Radix^Precision = One Ulp of numbers a little less than 1.0 .", + " Adequacy of guard digits for Mult., Div. and Subt.", + " Whether arithmetic is chopped, correctly rounded, or something else", + "\tfor Mult., Div., Add/Subt. and Sqrt.", + " Whether a Sticky Bit used correctly for rounding.", + " UnderflowThreshold = an underflow threshold.", + " E0 and PseudoZero tell whether underflow is abrupt, gradual, or fuzzy.", + " V = an overflow threshold, roughly.", + " V0 tells, roughly, whether Infinity is represented.", + " Comparisions are checked for consistency with subtraction", + "\tand for contamination with pseudo-zeros.", + " Sqrt is tested. Y^X is not tested.", + " Extra-precise subexpressions are revealed but NOT YET tested.", + " Decimal-Binary conversion is NOT YET tested for accuracy.", + 0}; + + msglist (chars); +} + +void +History () +{ /* History */ + /* Converted from Brian Wichmann's Pascal version to C by Thos Sumner, + with further massaging by David M. Gay. */ + + static char *hist[] = + { + "The program attempts to discriminate among", + " FLAWs, like lack of a sticky bit,", + " Serious DEFECTs, like lack of a guard digit, and", + " FAILUREs, like 2+2 == 5 .", + "Failures may confound subsequent diagnoses.\n", + "The diagnostic capabilities of this program go beyond an earlier", + "program called `MACHAR', which can be found at the end of the", + "book `Software Manual for the Elementary Functions' (1980) by", + "W. J. Cody and W. Waite. Although both programs try to discover", + "the Radix, Precision and range (over/underflow thresholds)", + "of the arithmetic, this program tries to cope with a wider variety", + "of pathologies, and to say how well the arithmetic is implemented.", + "\nThe program is based upon a conventional radix representation for", + "floating-point numbers, but also allows logarithmic encoding", + "as used by certain early WANG machines.\n", + "BASIC version of this program (C) 1983 by Prof. W. M. Kahan;", + "see source comments for more history.", + 0}; + + msglist (hist); +} diff --git a/lib/CPUs/MIPS/bsp/examples/phrasen.c b/lib/CPUs/MIPS/bsp/examples/phrasen.c new file mode 100644 index 0000000..08abf97 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/phrasen.c @@ -0,0 +1,298 @@ +#include +#include +#include "libsys.h" + +struct substantive +{ + char *subst; + int sex; +}; + +struct verben +{ + char *verb_k; + char *verb_gr; + int art; +}; + +struct adjektive +{ + char *adj; +}; + + char *art[4]={"er","ie","as","en"}; + +char getch(void) +{ + return _getchar(); +} + +void randomize(void) +{ + srand(clock()); +} + +struct substantive namen[]= +{ + {"Gerhard Schröder",1},{"Helmut Kohl",1},{"Rudolf Scharping",1}, + {"Claudia Nolte",2}, {"Johannes Rau",1},{"Wolfgang Schäuble",1}, + {"Joschka Fischer",1},{"Toni Blair",1},{"Kleopatra",2}, + {"Claudia Schiffer",2},{"Hannelore Kohl",2},{"Konrad Adenauer",1}, + {"Michael Jackson",1},{"Karl Marx",1}, {"Helmut Kohl",1},{"Heino",1}, + {"Gerhard Schröder",1},{"Donald Duck",1},{"Madonna",2},{"Jesus",1}, + {"Gott",1},{"Sheryl Crow",2},{"Verona Feldbusch",2},{"Pipi Langstrumpf",2}, + {"Bill Gates",1},{"Bill Clinton",1},{"Cleopatra",2},{"Winnetou",1}, + {"Käpt'n Blaubär",1},{"Rita Süssmuth",2},{"Boris Becker",1}, + {"Lilo Wanders",2},{"Queen Elizabeth",2},{"Lady Di",2},{"Steffi Graf",2}, + {"Frank Zappa",1},{"Dolly Buster",2},{"Mao Tse Tung",1},{"Ghandi",1}, + {"Dalai Lama",1},{"Teufel",1},{"Lenin",1},{"Edmund Stoiber",1}, + {"Ludwig van Beethoven",1},{"Wolfgang Amadeus Mozart",1}, + {"Richard Wagner",1},{"Erich Honecker",1},{"Adam Riese",1}, + {"Bill Clinton",1},{"Josef Stalin",1},{"Willy Brandt",1}, + {"John F. Kennedy",1},{"E.T.",1},{"Donald Duck",1},{"Lothar Matthäus",1}, + {"Hans Dietrich Genscher",1},{"Franz Josef Strauss",1},{"Sting",1}, + {"Hermann Hesse",1},{"Albert Einstein",1},{"Max Planck",1}, + {"Tom Jones",1},{"Heidi Kabel",2},{"Homer Simpson",1},{"Zeus",1}, + {"Helmut Schmidt",1},{"Antje Vollmer",2},{"Politiker",1},{"Papst",1}, + {"Bundeskanzler",1},{"Arzt",1},{"Friseuse",2},{"Teufel",1}, + {"Sandmännchen",3},{"Mutter",2},{"Vater",1},{"Säufer",1},{"Student",1}, + {"Bauer",1},{"Leiche",2},{"Polizist",1},{"Patientin",2},{"Bäcker",1}, + {"Wirt",1}, {"Schlachter",1},{"Baby",3},{"Reporter",1},{"Politiker",1}, + {"Beamtin",2},{"Oma",2},{"Putzfrau",2},{"Blinde",2},{"Wahnsinnige",2}, + {"Mörder",1},{"Psychiater",1},{"Prinz Charles",1},{"Onkel",1},{"Tante",2} +}; + +struct substantive sachen[]= +{ + {"Haus",3},{"Buch",3},{"Fahrrad",3},{"Schule",2},{"Auto",3},{"Nase",2}, + {"Mund",1},{"Kopf",1},{"Kaffee",1},{"Telephon",3},{"Tasse",2},{"Katze",2}, + {"Hund",1},{"Maus",2},{"Stuhl",1},{"Mann",1},{"Frau",2},{"Kind",3}, + {"Idiotin",2},{"Lampe",2},{"Panzer",1},{"Klavier",3},{"Gitarre",2}, + {"Straße",2},{"Wasser",3},{"Luft",2},{"Feuer",3},{"Erde",2},{"Mond",1}, + {"Sonne",2},{"Bild",3},{"Stadt",2},{"Land",3},{"Fluss",1}, + {"Bundeskanzler",1},{"Ball",1},{"Hut",1},{"Hose",2},{"Hemd",3},{"Tod",1}, + {"Geld",3},{"Tisch",1},{"Hand",2},{"Baum",1},{"Bier",3},{"Ratte",2}, + {"Esel",1},{"Musik",2},{"Blech",3},{"Dose",2},{"Zahn",1},{"Humor",1}, + {"Unterhose",2},{"Gift",3},{"Gesicht",3},{"Fuß",1},{"Auge",3},{"Warze",2}, + {"Ohr",3},{"Kanone",2},{"Milch",2},{"Messer",3},{"Papier",3},{"Haar",3}, + {"Welt",2},{"Motor",1},{"Langeweile",2},{"Grab",3},{"Schnaps",1}, + {"Vogel",1},{"Fisch",1},{"Meer",3},{"Banane",2},{"Brot",3}, + {"Sitzung",2},{"Labor",3},{"Kurzschluß",1},{"Lüge",2},{"Axt",2}, + {"Abstimmung",2},{"Toilette",2},{"Zigarette",2},{"Winter",1}, + {"Torte",2},{"Bahnhof",1},{"Sarg",1},{"Imbiss",1},{"Mund",1},{"Seife",2}, + {"Fernseher",1},{"Flasche",2},{"Eimer",1},{"Uhr",2},{"Irrenhaus",3}, + {"Wüste",2},{"Klumpen",1},{"Glück",3},{"Schiff",3},{"Käse",1},{"Quark",1}, + {"Sommer",1},{"Witz",1},{"Idee",2},{"Nacht",2},{"Dreck",1},{"Meer",3}, + {"Blut",3},{"Herz",3},{"Apfel",1},{"Banane",2},{"Mist",1},{"Atom",3}, + {"Note",2},{"Gehirn",3},{"Gefühl",3},{"Bombe",2},{"Vakuum",3}, + {"Zahl",2},{"Wort",3},{"Programm",3},{"Computer",1},{"Orient",1}, + {"Gabelstapler",1} +}; + +struct adjektive ad[]= +{ + {"schön"},{"doof"},{"gut"},{"schlecht"},{"gelb"},{"grün"},{"rot"}, + {"blau"},{"schnell"},{"lang"},{"kurz"},{"hell"},{"düster"},{"sanft"}, + {"hart"},{"langsam"},{"bitter"},{"süß"},{"kaputt"},{"nett"},{"groß"}, + {"klein"},{"leicht"},{"schwer"},{"dick"},{"dünn"},{"rund"},{"eckig"}, + {"heiß"},{"kalt"},{"schlau"},{"elektrisch"},{"nass"},{"trocken"},{"ratlos"}, + {"abartig"},{"genial"},{"bestechlich"},{"irr"},{"steif"},{"angespannt"}, + {"laut"},{"leis"},{"warm"},{"wütend"},{"sauber"},{"schmutzig"},{"arm"}, + {"ätzend"},{"langweilig"},{"interessant"},{"erfahren"},{"abgewählt"}, + {"durchgeknallt"},{"angenehm"},{"widerwärtig"},{"willig"},{"mutig"}, + {"schwach"},{"stark"},{"nervend"},{"spießig"},{"alt"},{"neu"},{"spitz"}, + {"stumpf"},{"teuflisch"},{"scharf"},{"lecker"},{"übelriechend"},{"halb"}, + {"ganz"},{"bleich"},{"peinlich"},{"taktlos"},{"gewieft"},{"windig"}, + {"größenwahnsinnig"},{"verrückt"},{"uralt"},{"aalglatt"},{"korrekt"}, + {"kompetent"},{"einfühlsam"},{"tot"},{"schleimig"},{"gestört"},{"hohl"}, + {"beknackt"},{"nackt"},{"barfüßig"},{"schwitzend"},{"laufend"},{"knackig"}, + {"unverschämt"},{"schläfrig"},{"wohlgeformt"},{"kugelförmig"},{"rauh"}, + {"degeneriert"},{"ekelhaft"},{"brutal"},{"gemein"},{"aggressiv"}, + {"aufdringlich"},{"betroffen"},{"geliebt"},{"gehasst"},{"beharrlich"}, + {"unmenschlich"},{"verblödet"},{"wichtig"},{"gigantisch"},{"winzig"}, + {"witzig"},{"komisch"},{"pervers"},{"fett"},{"stinkend"},{"lausig"}, + {"wendig"},{"breit"},{"locker"},{"einzigartig"},{"sterbend"},{"munter"}, + {"ungepflegt"},{"eisern"},{"echt"},{"besser"},{"wild"},{"ächzend"}, + {"frohlockend"},{"unscheinbar"},{"nebulös"},{"skandalös"},{"obzön"}, + {"beschränkt"},{"genervt"},{"hilflos"},{"unwürdig"},{"geleckt"}, + {"betrunken"},{"unwürdig"},{"bissig"},{"verkalkt"},{"senil"}, + {"jungfräulich"},{"ausgeleiert"},{"beleibt"},{"nachtragend"},{"errötend"}, + {"kahl"},{"würgend"},{"abwesend"},{"ruhig"},{"albern"},{"trostlos"}, + {"salzig"},{"lachend"},{"merkwürdig"},{"behaart"},{"leblos"},{"aufgeblasen"}, + {"frech"},{"kopflos"},{"schmierig"} +}; + +struct verben verb[]= +{ + {"geht","gehen",6},{"steht","stehen",2},{"sitzt","sitzen",2}, + {"spielt","spielen",7},{"singt","singen",2},{"trinkt","trinken",3}, + {"redet","reden",2}, {"liebt","lieben",7},{"schläft","schlafen",2}, + {"ißt","essen",3},{"lacht","lachen",2},{"tötet","töten",7}, + {"lügt","lügen",2},{"fliegt","fliegen",2},{"überfährt","überfahren",7}, + {"sieht","sehen",3},{"hört","hören",3},{"spricht","sprechen",2}, + {"berechnet","rechnen",3},{"schwimmt","schwimmen",2}, + {"zerschneidet","zerschnitten werden",3},{"raucht","rauchen",3}, + {"spaltet","spalten",3},{"verbrennt","verbrennen",2},{"ist","sein",2}, + {"hat","haben",1},{"zerbricht","zerbrechen",3},{"muss","müssen",4}, + {"kann","können",4},{"darf","dürfen",4},{"will","wollen",5}, + {"klaut","klauen",1},{"soll","sollen",4},{"studiert","studieren",3}, + {"reibt","reiben",3},{"liest","lesen",2},{"irrt","irren",2}, + {"spendiert","spendieren",1},{"schlägt","schlagen",3},{"fragt","fragen",7}, + {"zerstört","zerstören",1},{"erschießt","sich erschießen",1}, + {"überlegt","überlegen",2},{"trifft","treffen",7},{"leckt","lecken",1}, + {"wirft","werfen",1},{"vergiftet","vergiftet werden",1}, + {"öffnet","öffnen",1},{"schreit","schreien",2},{"sprengt","explodieren",3}, + {"erwürgt","würgen",7},{"arbeitet","arbeiten",2},{"erlegt","erlegen",1}, + {"putzt","putzen",1},{"stirbt","sterben",2}, {"kauft","kaufen",1}, + {"brüllt","brüllen",2},{"versteht","es verstehen",7}, + {"zertritt","zertreten werden",1},{"verendet","verenden",2}, + {"labert","labern",2},{"kratzt","kratzen",1},{"wird","nichts werden",2}, + {"entkleidet","sich entkleiden",7},{"verbiegt","sich verbiegen",1}, + {"verschenkt","es verschenken",7},{"vergisst","es vergessen",1}, + {"ergreift","greifen",1},{"baut","bauen",1},{"betet","beten",}, + {"rollt","rollen",3},{"bleibt","bleiben",2},{"wäscht","sich waschen",1}, + {"heiratet","heiraten",7},{"hebt","heben",1},{"denkt","nachdenken",2} +}; + +void end_sach_aus(void); +void nam_aus(void); +void end_nam_aus(void); +void adj_aus(void); +int verb_aus_k(void); +int verb_aus_gr(void); +int zufall(int); + +int main() +{ + int vindx; + int rem=0; + char end; + + setbuf(stdout, NULL); + randomize(); + printf("\n\t\t************************"); + printf("\n\t\t* DER ELEKTRISCHE POET *"); + printf("\n\t\t************************\n"); + printf("\n\tCopyright by J. Ahrensfeld & T. Burr"); + printf("\n\n\tFür die Texte ist Ihr Computer verantwortlich :-)\n"); + printf("\n\tZum beenden des Programmes 'x' eingeben!\n"); + printf("\n\tWeiter mit beliebiger Taste!\n"); + end = getch(); + + while(end != 'x') + { + if(rem >= 10) + { + printf("\n\n\tZum beenden des Programmes 'x' eingeben!\n"); + rem = 0; + if(getch() == 'x') + break; + } + printf("\n\n"); + nam_aus(); + + vindx=verb_aus_k(); + + switch (vindx) + { + case 1: end_sach_aus(); break; + + case 2: adj_aus(); break; + + case 3: end_sach_aus(); break; + + case 4: verb_aus_gr(); break; + + case 5: verb_aus_gr(); break; + + case 6: adj_aus(); break; + + case 7: end_nam_aus(); break; + } + + printf("."); + end = getch(); + rem++; + + } + printf("\n\n\tDas ist das Ende!"); + return 0; +} + +int zufall(int max) +{ + + return (rand()%max); +} + +void adj_aus(void) +{ + printf("%s", ad[zufall((sizeof(ad)/sizeof(*ad)))].adj); + return; +} + +void end_sach_aus(void) +{ + int index; + + index = zufall(sizeof(sachen)/sizeof(*sachen)); + if (sachen[index].sex==1) + printf("d%s", art[3]); + else + printf("d%s", art[(sachen[index].sex)-1]); + printf(" "); + adj_aus(); + if (sachen[index].sex==1) + printf("en %s", sachen[index].subst); + else + printf("e %s", sachen[index].subst); + return; +} + +void nam_aus(void) +{ + int index; + + index = zufall(sizeof(namen)/sizeof(*namen)); + printf("D%s", art[(namen[index].sex)-1]); + printf(" "); + adj_aus(); + printf("e %s " ,namen[index].subst); + return; +} + +void end_nam_aus(void) +{ + int index; + + index = zufall(sizeof(namen)/sizeof(*namen)); + if (namen[index].sex==1) + printf("d%s", art[3]); + else + printf("d%s", art[(namen[index].sex)-1]); + printf(" "); + adj_aus(); + if (namen[index].sex==1) + printf("en %s", namen[index].subst); + else + printf("e %s", namen[index].subst); + return; +} + +int verb_aus_k(void) +{ + int index; + + index = zufall(sizeof(verb)/sizeof(*verb)); + printf("%s ", verb[index].verb_k); + return (verb[index].art); +} + +int verb_aus_gr(void) +{ + int index; + + index = zufall(sizeof(verb)/sizeof(*verb)); + printf("%s", verb[index].verb_gr); + return index; +} diff --git a/lib/CPUs/MIPS/bsp/examples/pi.h b/lib/CPUs/MIPS/bsp/examples/pi.h new file mode 100644 index 0000000..5cfed9b --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/pi.h @@ -0,0 +1,13 @@ +/* +++Date last modified: 05-Jul-1997 */ + +#ifndef PI__H +#define PI__H + +#ifndef PI + #define PI (4*atan(1)) +#endif + +#define deg2rad(d) ((d)*PI/180) +#define rad2deg(r) ((r)*180/PI) + +#endif /* PI__H */ diff --git a/lib/CPUs/MIPS/bsp/examples/queens.c b/lib/CPUs/MIPS/bsp/examples/queens.c new file mode 100644 index 0000000..f9735e6 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/queens.c @@ -0,0 +1,856 @@ +/* +** Queens.c -- Find solutions to the Eight-Queens chess problem. +** Roberto Sierra 7/25/93 Version 1.1 +** 3/19/84 Version 1.0 +** +** Description: +** This program finds all the possible ways that N queens can +** be placed on an NxN chessboard so that the queens cannot +** capture one another -- that is, so that no rank, file or +** diagonal is occupied by more than one queen. By default, +** the program prints the first solution it finds. You can +** use the -a option to print all solutions, or the -c option +** just to count them. The program allows the chess board +** to be from 1x1 (trivial case) to 100x100. Warning: the +** larger the chess board, the longer it typically takes to +** find each solution, even though there may be more of them. +** +** This is a terrific example of the utility of recursion. The +** algorithm uses recursion to drastically limit the number +** of board positions that are tested. The program is able +** to find all 8x8 queen solutions in a fraction of a second +** (not counting print time). The code makes no attempt to +** eliminate symmetrical solutions, so the number of solutions +** reported will always be higher than the actual number of +** distinct solutions. +** +** +** Usage: +** Queens [-ac] n +** +** n number of queens (rows and columns). +** An integer from 1 to 100. +** -a Find (and print) all solutions. +** -c Count all solutions, but do not print them. +** +** The output is sent to stdout. All errors messages are +** sent to stderr. If a problem arises, the return code is -1. +** +** +** Examples: +** +** Queens 8 ## Show an 8x8 solution +** 8 queens on a 8x8 board... +** Q - - - - - - - +** - - - - Q - - - +** - - - - - - - Q +** - - - - - Q - - +** - - Q - - - - - +** - - - - - - Q - +** - Q - - - - - - +** - - - Q - - - - +** +** Queens -c 8 ## Count all 8x8 solutions +** 8 queens on a 8x8 board... +** ...there are 92 solutions. +** +** Queens -a 4 ## Show all 4x4 solutions +** 4 queens on a 4x4 board... +** +** Solution #1: +** - Q - - +** - - - Q +** Q - - - +** - - Q - +** +** Solution #2: +** - - Q - +** Q - - - +** - - - Q +** - Q - - +** +** ...there are 2 solutions. +** +** +** Build Instructions: +** You'll need an ANSI C compiler (or the willingness to edit +** the program a bit). If you've got Gnu C, then you can +** compile and load the program as follows: +** +** gcc Queens.c -ansi -o Queens +** +** [If you're using MPW on the Mac, define '-d MPW' on the +** compile line so that background processing will occur.] +** +** +** Algorithm: +** In a 1984 Byte article, I ran across an interesting letter +** from a high school student who was attempting to solve the +** Eight Queens problem using a BASIC interpreter. He had +** developed a program which placed eight queens successively +** on all sixty-four squares, testing for conflicts at each +** iteration. Of course, such a program would require 64^8 +** iterations (about 2.8x10^14 iterations). Even in C on a, +** fast CPU, this could take months or years. Byte's answer was +** to alter the loops so that the queens resided on separate +** ranks, thereby reducing the number of iterations required +** to find all solutions to 8^8 iterations (about 16 million). +** More reasonable, but still requiring a chunk of CPU time. +** +** I puzzled about this problem a bit, and came to realize that +** this was still wasting a lot of CPU cycles. Though I'm sure +** others have come up with good algorithms, I decided to come +** up with my own, with a particular eye on efficiency. The +** resulting algorithm finds all 8x8 solutions in a fraction +** of a second (there are 92 solutions, including rotations). +** On a Sun 4, it'll find all 365,596 solutions on a 14x14 board +** in a bit over 2 minutes (printing them out requires extra +** time, of course). Even Byte's solution would require 14^14 +** iterations (about 10^16) which would take aeons. +** +** My algorithm works as follows: +** (1) Place a queen in the top left corner. +** (2) Place another queen immediately below. +** (3) Test for conflicts. If the second queen conflicts (it +** does at first), then move it one square to the right. +** (4) Loop step 3 until there are no conflicts. Place +** the next queen on the board and recurse. +** (5) If any queen reaches the right edge of the board, +** remove it and 'pop' to the previous recursion level. +** (6) Now repeat these steps recursively until all eight +** queens (or however many) have been placed without +** conflict -- the result is a solution to the problem, +** which is counted and optionally printed. +** +** Because conflicts are tested as the recursion proceeds, +** this has the effect of 'pruning' the recursion so that +** a large number of board positions are not even attempted. +** The result is that the algorithm runs in reasonable time. +** +** I used a few tricks to make the test-for-conflict code +** extremely efficient -- there is no 'inner' loop to search +** along ranks, files, or diagonals. A series of arrays are +** maintained instead which indicate which queen currently +** 'owns' each rank, file or diagonal. This makes the +** algorithm really fly, though the code is a little hard to +** read. Lastly, pointer arithmetic is used to reduce the +** number of implicit multiplications used in array addressing. +** +** +** Contact: +** For queries regarding this program, contact Roberto Sierra +** at any of the following addresses: +** +** Roberto Sierra +** bert@netcom.com (preferred address) +** 73557.2101@compuserve.com +** +** Tempered MicroDesigns +** P.O. Box 170638 +** San Francisco, CA 94117 +** +** +** Fine Print: +** This program is in the public domain and can be used for +** any purpose whatsoever, including commercial application. +** [I'd like to hear what you do with it, though.] +** Absolutely no warranty or liability is implied or extended +** by the author. +** +** +** Modification History: +** PRS 3/19/84 v1.0 -- Original version. +** PRS 7/25/93 v1.1 -- ANSIfied the code. More efficient pointers. +** +*/ + +/***************************************************************/ +/* Timer options. You MUST uncomment one of the options below */ +/* or compile, for example, with the '-DUNIX' option. */ +/***************************************************************/ +/* #define Amiga */ +/* #define UNIX */ +/* #define UNIX_Old */ +/* #define VMS */ +/* #define BORLAND_C */ +/* #define MSC */ +/* #define MAC */ +/* #define IPSC */ +/* #define FORTRAN_SEC */ +/* #define GTODay */ +/* #define CTimer */ +/* #define UXPM */ +/* #define MAC_TMgr */ +/* #define PARIX */ +/* #define POSIX */ +/* #define WIN32 */ +/* #define POSIX1 */ +/***********************/ + +#include /* Need standard I/O functions */ +#include /* Need exit() routine interface */ +#include /* Need strcmp() interface */ +#ifdef MPW /* Macintosh MPW ONLY */ +#include /* Need cursor control interfaces */ +#endif + +#define MAXQUEENS 100 /* Maximum number of queens */ +#define MAXRANKS MAXQUEENS /* Maximum number of ranks (rows) */ +#define MAXFILES MAXQUEENS /* Maximum number of files (columns) */ +#define MAXDIAGS (MAXRANKS+MAXFILES-1) /* Maximum number of diagonals */ +#define EMPTY (MAXQUEENS+1) /* Marks unoccupied file or diagonal */ + +/* GLOBAL VARIABLES */ + +int queens; /* Number of queens to place */ +int ranks; /* Number of ranks (rows) */ +int files; /* Number of files (columns) */ +int printing = 1; /* TRUE if printing positions */ +int findall = 0; /* TRUE if finding all solutions */ + +unsigned long solutions = 0; /* Number of solutions found */ +int queen[MAXRANKS]; /* File on which each queen is located */ +int file[MAXFILES]; /* Which queen 'owns' each file */ +int fordiag[MAXDIAGS]; /* Which queen 'owns' forward diagonals */ +int bakdiag[MAXDIAGS]; /* Which queen 'owns' reverse diagonals */ +char *progname = 0; /* The name of this program */ + + + + + +/***********************/ +/**** ROUTINES ****/ +/***********************/ + +/* Internal prototypes */ +//void main(int argc,char **argv); /* Main program */ +void find(int level); /* Algorithm to find solutions */ +void pboard(void); /* Print a solution */ +void run_queens(int argc,char **argv); + + + + +/*---------------------- main() --------------------------- +** MAIN program. The main purpose of this routine is +** to deal with decoding the command line arguments, +** initializing the various arrays, and starting the +** recursive search routine. +*/ +int main(void) +{ + char *args[] = {"queens", "-c", "12"}; + run_queens(3, args); +} + +void run_queens(int argc,char **argv) +{ + register int i; /* Loop variable */ + register char *p; /* Pointer to argument */ + double starttime, benchtime, dtime(); + +#ifdef MPW /* Macintosh MPW ONLY */ + InitCursorCtl(0); /* Enable cursor control */ +#endif + + progname = argv[0]; /* The name of the program */ + + /**** DECODE COMMAND LINE ARGUMENTS ****/ + + for (i=1; i MAXQUEENS) { /* N can't be too large */ + fprintf(stderr,"%s: can't have more than %d queens\n", + progname, MAXQUEENS); + exit(-1); + } + } /* End of argument test */ + } /* End of argument scan loop */ + if (queens == 0) { + fprintf(stderr,"%s: missing queens argument\n",progname); + fprintf(stderr,"usage: %s [-ac] queens\n",progname); + exit(-1); + } + + + ranks = files = queens; /* NxN board for N queens */ + printf("%d queen%s on a %dx%d board...\n", + queens, queens>1? "s" : "", ranks, files); + fflush(stdout); + + starttime = dtime(); + + /* Initialization */ + solutions = 0; /* No solutions yet */ + for (i=0; i= level && /* No queen on the file? */ + *fdp >= level && *bdp >= level /* No queens on diagonals? */ + ) { + queen[level] = f; /* Note new position of queen */ + *fp = *fdp = *bdp = level; /* Place queen on file & diags */ + find(level+1); /* This level OK, recurse to next */ + *fp = *fdp = *bdp = EMPTY; /* Remove queen from file & diags */ + } /* End of conflict test */ + } /* End of file loop */ + } /* End if (level == queens) */ +} /* End of find() */ + + + + +/*------------------------- pboard() ----------------------- +** This routines prints the board for a particular solution. +** The output is sent to stdout. +*/ + +void pboard(void) +{ + register int i,j; /* Rank/File indices */ + + if (findall) { /* Only if searching for all */ + printf("\nSolution #%lu:\n",solutions); /* Print solution number */ + } + for (i=0; i +#define HZ 50 + +double dtime() +{ + double q; + + struct tt + { + long days; + long minutes; + long ticks; + } tt; + + DateStamp(&tt); + + q = ((double)(tt.ticks + (tt.minutes * 60L * 50L))) / (double)HZ; + + return q; +} +#endif + +/*****************************************************/ +/* UNIX dtime(). This is the preferred UNIX timer. */ +/* Provided by: Markku Kolkka, mk59200@cc.tut.fi */ +/* HP-UX Addition by: Bo Thide', bt@irfu.se */ +/*****************************************************/ +#ifdef UNIX +#include +#include + +#ifdef hpux +#include +#define getrusage(a,b) syscall(SYS_getrusage,a,b) +#endif + +struct rusage rusage; + +double dtime() +{ + double q; + + getrusage(RUSAGE_SELF,&rusage); + + q = (double)(rusage.ru_utime.tv_sec); + q = q + (double)(rusage.ru_utime.tv_usec) * 1.0e-06; + + return q; +} +#endif + +/***************************************************/ +/* UNIX_Old dtime(). This is the old UNIX timer. */ +/* Make sure HZ is properly defined in param.h !! */ +/***************************************************/ +#ifdef UNIX_Old +#include +#include +#include + +#ifndef HZ +#define HZ 60 +#endif + +struct tms tms; + +double dtime() +{ + double q; + + times(&tms); + + q = (double)(tms.tms_utime) / (double)HZ; + + return q; +} +#endif + +/*********************************************************/ +/* VMS dtime() for VMS systems. */ +/* Provided by: RAMO@uvphys.phys.UVic.CA */ +/* Some people have run into problems with this timer. */ +/*********************************************************/ +#ifdef VMS +#include time + +#ifndef HZ +#define HZ 100 +#endif + +struct tbuffer_t + { + int proc_user_time; + int proc_system_time; + int child_user_time; + int child_system_time; + }; + +struct tbuffer_t tms; + +double dtime() +{ + double q; + + times(&tms); + + q = (double)(tms.proc_user_time) / (double)HZ; + + return q; +} +#endif + +/******************************/ +/* BORLAND C dtime() for DOS */ +/******************************/ +#ifdef BORLAND_C +#include +#include +#include + +#define HZ 100 +struct time tnow; + +double dtime() +{ + double q; + + gettime(&tnow); + + q = 60.0 * (double)(tnow.ti_min); + q = q + (double)(tnow.ti_sec); + q = q + (double)(tnow.ti_hund)/(double)HZ; + + return q; +} +#endif + +/**************************************/ +/* Microsoft C (MSC) dtime() for DOS */ +/**************************************/ +#ifdef MSC +#include +#include + +#define HZ CLOCKS_PER_SEC +clock_t tnow; + +double dtime() +{ + double q; + + tnow = clock(); + + q = (double)tnow / (double)HZ; + + return q; +} +#endif + +/*************************************/ +/* Macintosh (MAC) Think C dtime() */ +/*************************************/ +#ifdef MAC +#include + +#define HZ 60 + +double dtime() +{ + double q; + + q = (double)clock() / (double)HZ; + + return q; +} +#endif + +/************************************************************/ +/* iPSC/860 (IPSC) dtime() for i860. */ +/* Provided by: Dan Yergeau, yergeau@gloworm.Stanford.EDU */ +/************************************************************/ +#ifdef IPSC +extern double dclock(); + +double dtime() +{ + double q; + + q = dclock(); + + return q; +} +#endif + +/**************************************************/ +/* FORTRAN dtime() for Cray type systems. */ +/* This is the preferred timer for Cray systems. */ +/**************************************************/ +#ifdef FORTRAN_SEC + +fortran double second(); + +double dtime() +{ + double q; + + second(&q); + + return q; +} +#endif + +/***********************************************************/ +/* UNICOS C dtime() for Cray UNICOS systems. Don't use */ +/* unless absolutely necessary as returned time includes */ +/* 'user+system' time. Provided by: R. Mike Dority, */ +/* dority@craysea.cray.com */ +/***********************************************************/ +#ifdef CTimer +#include + +double dtime() +{ + double q; + clock_t clock(void); + + q = (double)clock() / (double)CLOCKS_PER_SEC; + + return q; +} +#endif + +/********************************************/ +/* Another UNIX timer using gettimeofday(). */ +/* However, getrusage() is preferred. */ +/********************************************/ +#ifdef GTODay +#include + +struct timeval tnow; + +double dtime() +{ + double q; + + gettimeofday(&tnow,NULL); + q = (double)tnow.tv_sec + (double)tnow.tv_usec * 1.0e-6; + + return q; +} +#endif + +/*****************************************************/ +/* Fujitsu UXP/M timer. */ +/* Provided by: Mathew Lim, ANUSF, M.Lim@anu.edu.au */ +/*****************************************************/ +#ifdef UXPM +#include +#include +struct tmsu rusage; + +double dtime() +{ + double q; + + timesu(&rusage); + + q = (double)(rusage.tms_utime) * 1.0e-06; + + return q; +} +#endif + +/**********************************************/ +/* Macintosh (MAC_TMgr) Think C dtime() */ +/* requires Think C Language Extensions or */ +/* #include in the prefix */ +/* provided by Francis H Schiffer 3rd (fhs) */ +/* skipschiffer@genie.geis.com */ +/**********************************************/ +#ifdef MAC_TMgr +#include +#include + +static TMTask mgrTimer; +static Boolean mgrInited = false; +static double mgrClock; + +#define RMV_TIMER RmvTime( (QElemPtr)&mgrTimer ) +#define MAX_TIME 1800000000L +/* MAX_TIME limits time between calls to */ +/* dtime( ) to no more than 30 minutes */ +/* this limitation could be removed by */ +/* creating a completion routine to sum */ +/* 30 minute segments (fhs 1994 feb 9) */ + +static void Remove_timer( ) +{ + RMV_TIMER; + mgrInited = false; +} + +double dtime( ) +{ + if( mgrInited ) { + RMV_TIMER; + mgrClock += (MAX_TIME + mgrTimer.tmCount)*1.0e-6; + } else { + if( _atexit( &Remove_timer ) == 0 ) mgrInited = true; + mgrClock = 0.0; + } + + if ( mgrInited ) + { + mgrTimer.tmAddr = NULL; + mgrTimer.tmCount = 0; + mgrTimer.tmWakeUp = 0; + mgrTimer.tmReserved = 0; + InsTime( (QElemPtr)&mgrTimer ); + PrimeTime( (QElemPtr)&mgrTimer, -MAX_TIME ); + } + return( mgrClock ); +} +#endif + +/***********************************************************/ +/* Parsytec GCel timer. */ +/* Provided by: Georg Wambach, gw@informatik.uni-koeln.de */ +/***********************************************************/ +#ifdef PARIX +#include + +double dtime() +{ + double q; + + q = (double) (TimeNowHigh()) / (double) CLK_TCK_HIGH; + + return q; +} +#endif + +/************************************************/ +/* Sun Solaris POSIX dtime() routine */ +/* Provided by: Case Larsen, CTLarsen.lbl.gov */ +/************************************************/ +#ifdef POSIX +#include +#include +#include + +#ifdef __hpux +#include +#endif + +struct rusage rusage; + +double dtime() +{ + double q; + + getrusage(RUSAGE_SELF,&rusage); + + q = (double)(rusage.ru_utime.tv_sec); + q = q + (double)(rusage.ru_utime.tv_nsec) * 1.0e-09; + + return q; +} +#endif + + +/****************************************************/ +/* Windows NT (32 bit) dtime() routine */ +/* Provided by: Piers Haken, piersh@microsoft.com */ +/****************************************************/ +#ifdef WIN32 +#include + +double dtime(void) +{ + double q; + + q = (double)GetTickCount() * 1.0e-03; + + return q; +} +#endif + +/*****************************************************/ +/* Time according to POSIX.1 - */ +/* Ref: "POSIX Programmer's Guide" O'Reilly & Assoc.*/ +/*****************************************************/ +#ifdef POSIX1 +#define _POSIX_SOURCE 1 +#include +#include +#include + +struct tms tms; + +double dtime() +{ + double q; + times(&tms); + q = (double)tms.tms_utime / (double)CLK_TCK; + return q; +} +#endif + +/*-------- End of queens.c, Say goodnight Linda! --------*/ diff --git a/lib/CPUs/MIPS/bsp/examples/r3.c b/lib/CPUs/MIPS/bsp/examples/r3.c new file mode 100644 index 0000000..adba0bc --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/r3.c @@ -0,0 +1,471 @@ +/* + * IOCCC Raytracer by Anders Gavare. + * + * The raytracer was one of the winners of the 17th IOCCC. + * + * NOTE: This is the UNOBFUSCATED version of the raytracer I used + * during development, not the actual entry sent to the contest. + * + * + * How to build: + * cc r3.c -o r3 (plus optimization flags) + * + * How to run: + * ./r3 > ray.ppm + * or + * ./r3 | xv - + */ +#include "libsys.h" +UINT32 *pP; + +xsize = 800; +ysize = 600; +An = 1; + +camera_X = 0; +camera_Y = -10; +camera_Z = -7; + +scale = 1296; +RootOfScale = 36; +maxcolor = 255; + +MaxDepth=9; +_=1<<15; + +/* +double sphere_x[44] = { + -15,-15,-15,-15, // I + -8,-8,-10,-6,-10,-6, // O + -1,-1, 1,1, // C + 6, 6, 8,8, // C + 13,13,15,15, // C + -11,-11,-11,-11,-9,-9,-7,-7, // r + 0,0,-2,-2,-2,2,2,2, // a + 7,7,9,9,11,11, // y + }; +double sphere_z[44] = { + 3,0,-3,-6, // I + -6, 3,0,0,-3,-3, // O + 0,-3,-6, 3, // C + 0,-3,-6, 3, // C + 0,-3,-6, 3, // C + -11,-13,-15,-17,-11,-15,-13,-17, // r + -11,-15,-13,-15,-17,-13,-15,-17, // a + -11,-13,-15,-17,-11,-13, // y + }; +*/ + +/* Common return variable: */ +return_var; +return_var2; +return_var3; +return_var4; + + +get_sphere_coordinates(b) +{ + return_var = "1111886:6:??AAFFHHMMOO55557799@@>>>BBBGGIIKK"[b]-64; + return_var3 = "C@=::C@@==@=:C@=:C@=:C531/513/5131/31/531/53"[b]-64; + +/* return_var = sphere_x[b]; */ + return_var2 = b<22? 9 : 0; +/* return_var3 = sphere_z[b]; */ + return_var4 = 2; +} + + +/* sqroot(x) returns the square root of x in return_var */ +sqroot_sub(x, mask, guess) +{ + mask? + ( + guess ^= mask, + guess*guess > x ? + ( guess ^= mask ) + : + 0, + sqroot_sub(x, mask/2, guess) + ) + : + ( return_var = guess ); +} + + +sqroot(x) +{ + sqroot_sub(x, _, 0); +} + + +/* + * hit_sphere(): + * + * returns where on a sphere we hit + * Returns distance in hit_sphere_q. (Negative return + * value if we didn't hit anything.) + */ +hit_sphere_q; +hit_sphere(objnr, x, y, z, + dx, dy, dz, + a, b) +{ + get_sphere_coordinates(objnr); + x -= return_var*scale; + y -= return_var2*scale; + z -= return_var3*scale; + + /* + * Solve the following equation: + * + * q^2 (dx^2+dy^2+dz^2) + q * 2(x*dx+y*dy+z*dz) + * + x^2+y^2+z^2 - r^2 = 0 + * + * We assume that |dx,dy,dz| is 1. + * + * q^2 + a q + b = 0 + * + * The solution is (of course) + * + * q = -a/2 +- sqrt(a^2/4 - b) + */ + + b = x*x/scale+y*y/scale+z*z/scale-return_var4*return_var4*scale; + + /* a = 2*(...), and then divide by -2 */ + a = -x*dx/scale-y*dy/scale-z*dz/scale; + + hit_sphere_q = + ( + (b = a*a/scale - b) >= 0 ? + ( +/* b = scale*sqrt((double)b/(double)scale), */ +/* sqroot(b*scale), */ + +/* sqroot_sub(b, _, 0), + b = return_var * RootOfScale, +*/ + sqroot_sub(b*scale, _, 0), + b = return_var, + + /* + * Return the lowest q (a+b or a-b) which is more + * than 0. Return negative if neither + * a+b or a-b is more than 0. + */ + + a + (a>b? -b : b) + ) + : + -1.0 + ); +} + + +/* + * find_closest(): + * + * find_closest() scans objects and returns an index + * to the object which was closest (has the lowest 'q'). + * x,y,z,dx,dy,dz are scaled. + * find_closest_i is the index number of the found object, + * -1 if none was found. find_closest_q is the distance + * (scaled). + */ +find_closest_i; /* index ("sphere number") */ +find_closest_q; /* distance (scaled) */ +find_closest(objnr, x, y, z, + dx, dy, dz, notindex) +{ + /* Initialize find_closest_i on first call: */ + find_closest_i = + !objnr ? -1 : find_closest_i; + + objnr < 44 ? + ( + hit_sphere(objnr, x,y,z, dx,dy,dz, 0,0), + (hit_sphere_q > 0 && objnr!=notindex && + (hit_sphere_q0 && find_closest_i >= 0? + ( + /* find_closest_i and _q are the object + number and distance of the object we + hit. */ + + orig_x += dir_x*find_closest_q/scale, + orig_y += dir_y*find_closest_q/scale, + orig_z += dir_z*find_closest_q/scale, + + /* + * Calculate color (diffuse light): + * (Note: use nZ as a temp variable while + * calculating nY) + */ + get_sphere_coordinates(find_closest_i), + nX = orig_x - return_var*scale, + nY = orig_y - return_var2*scale, + nZ = orig_z - return_var3*scale, + + tmpcol = (-2*nX -2*nY + nZ) / 3, /* sqrt(9), */ + /* Set return_var to the length of the normal + vector (in this case the sphere radius) */ +/* return_var = sqrt(nX*nX + nY*nY +nZ*nZ), */ + sqroot(nX*nX + nY*nY +nZ*nZ), +// return_var = return_var4*scale, + /* divide by return_var to get the color */ +// tmpcol = return_var!=0? tmpcol*scale/return_var : 0, + tmpcol /= return_var4, + + /* color is now -1..1 */ + tmpcol *= tmpcol, /* square the color 1..-1 => 1..1 */ + tmpcol *= 200, + tmpcol /= (scale*scale), +/* tmpcol += 5, */ + + closest_i_saved = find_closest_i, + + /* Mirror: out = in - 2*(-normal)*cos v + where v is the angle between in and + -normal */ + + /* -normal: (normalized to len=1.0) */ +/* return_var = sqrt(nX*nX + nY*nY + nZ*nZ), */ + return_var!=0? + ( + nX = -nX * scale / return_var, + nY = -nY * scale / return_var, + nZ = -nZ * scale / return_var + ) : 0, + + /* use return_var as a temp variable, + calculate cosinus between the vectors */ + return_var = (dir_x*nX + dir_y*nY + dir_z*nZ)/scale, +/* + dir_x -= 2 * nX * return_var / scale, + dir_y -= 2 * nY * return_var / scale, + dir_z -= 2 * nZ * return_var / scale, +*/ + dir_x -= nX * return_var / (scale/2), + dir_y -= nY * return_var / (scale/2), + dir_z -= nZ * return_var / (scale/2), + + trace_ray(orig_x, orig_y, orig_z, + dir_x, dir_y, dir_z, + depth-1, find_closest_i, 0,0), + + trace_ray_R /= 2, + trace_ray_G /= 2, + trace_ray_B /= 2, +/* + closest_i_saved &= 7, + !closest_i_saved? (closest_i_saved++) : 0, +*/ +/* + closest_i_saved = closest_i_saved<4? closest_i_saved+1 : 7, +*/ +/* + tvinga gråskalor: closest_i_saved = 7, +*/ +closest_i_saved = closest_i_saved<22? 7 : + ( + closest_i_saved<30 ? 1 : + ( + closest_i_saved<38 ? 2 : + ( + closest_i_saved<44 ? 4 : + ( + closest_i_saved == 44 ? 6 : + 3 + ) + ) + ) + ), + + trace_ray_R += closest_i_saved & 1 ? tmpcol : 0, + trace_ray_G += closest_i_saved & 2 ? tmpcol : 0, + trace_ray_B += closest_i_saved & 4 ? tmpcol : 0 + ) + : + ( + /* If we didn't hit anything, set the color anyway: */ + + depth==MaxDepth? /* True if this is a ray originating + from the camera */ + ( + orig_z += 2, + dir_z = orig_z > 0? orig_z / 8 : orig_z / 20 + ) + : 0, + + /* + * Colors according to Horizon_1 in gimp: + * At top of sky: 13,92,146 (light blue) + * At bottom sky: 255,255,255 (white) + * Top of ground: 213,168,111 (light brown) + * Bottom of ground: 103, 55, 26 (brown) + */ + + dir_z > 0? + ( + trace_ray_B = dir_z * dir_z / scale, + trace_ray_R = 255 - 250 * trace_ray_B / scale, + trace_ray_G = 255 - 150 * trace_ray_B / scale, + trace_ray_B = 255 - 100 * trace_ray_B / scale + ) + : + ( + trace_ray_B = dir_z * dir_z / scale, + trace_ray_B < scale/5? + ( + trace_ray_R = 255 - 210 * trace_ray_B / scale, + trace_ray_G = 255 - 435 * trace_ray_B / scale, + trace_ray_B = 255 - 720 * trace_ray_B / scale + ) + : + ( + trace_ray_B -= scale/5, + trace_ray_R = 213 - 110 * trace_ray_B / scale, + trace_ray_G = 168 - 113 * trace_ray_B / scale, + trace_ray_B = 111 - 85 * trace_ray_B / scale + ) + ), + + depth!=MaxDepth? + ( + trace_ray_R /= 2, + trace_ray_G /= 2, + trace_ray_B /= 2 + ) + : 0 + ); + + trace_ray_R = trace_ray_R<0? 0 : trace_ray_R>maxcolor? maxcolor: trace_ray_R; + trace_ray_G = trace_ray_G<0? 0 : trace_ray_G>maxcolor? maxcolor : trace_ray_G; + trace_ray_B = trace_ray_B<0? 0 : trace_ray_B>maxcolor? maxcolor : trace_ray_B; +} + + +/* + * do_pixels_in_line(): + * + * the horizontal "for loop" + */ +R; G; B; +dpil_helper(x,y, a,b) +{ + trace_ray( + scale*camera_X + scale*40*(An*x+a)/xsize/An - scale*20, + scale*camera_Y, + scale*camera_Z - scale*30*(An*y+b)/ysize/An + scale*15, + 0, scale, 0, MaxDepth, -1, 0,0); + + R += trace_ray_R; + G += trace_ray_G; + B += trace_ray_B; + + ++a +#include "snipmath.h" + +#undef rad2deg /* These are macros defined in PI.H */ +#undef deg2rad + +double rad2deg(double rad) +{ + return (180.0 * rad / (PI)); +} + +double deg2rad(double deg) +{ + return (PI * deg / 180.0); +} + +#ifdef TEST + +#include + +main() +{ + double X; + + for (X = 0.0; X <= 360.0; X += 45.0) + printf("%3.0f degrees = %.12f radians\n", X, deg2rad(X)); + puts(""); + for (X = 0.0; X <= (2 * PI + 1e-6); X += (PI / 6)) + printf("%.12f radians = %3.0f degrees\n", X, rad2deg(X)); + return 0; +} + +#endif /* TEST */ diff --git a/lib/CPUs/MIPS/bsp/examples/random.c b/lib/CPUs/MIPS/bsp/examples/random.c new file mode 100644 index 0000000..c5f6615 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/random.c @@ -0,0 +1,86 @@ +/* random.c + + Author: Numerical recipes (ran1, gaussian), Jon Hamkins (others) + Revised by: Jon Hamkins + Date: 4-16-98 +*/ + +#include + +#define IA 16807 +#define IM 2147483647 +#define AM (1.0/IM) +#define IQ 127773 +#define IR 2836 +#define NTAB 32 +#define NDIV (1+(IM-1)/NTAB) +#define EPS 1.2e-14 +#define RNMX (1.0-EPS) +/* From Numerical Recipes, p. 280, modified from float to double */ +/* returns a uniform deviate in (0,1) */ +double ran1(long *idum) +{ + int j; + long k; + static long iy=0; + static long iv[NTAB]; + double temp; + + if (*idum <=0 || !iy) { + if (-(*idum) < 1) *idum=1; + else *idum = -(*idum); + for (j=NTAB+7; j>=0; j--) { + k=(*idum)/IQ; + *idum=IA*(*idum-k*IQ)-IR*k; + if (*idum < 0) *idum += IM; + if (j < NTAB) iv[j] = *idum; + } + iy = iv[0]; + } + k=(*idum)/IQ; + *idum=IA*(*idum-k*IQ)-IR*k; + if (*idum < 0) *idum += IM; + j=iy/NDIV; + iy=iv[j]; + iv[j] = *idum; + if ((temp=AM*iy) > RNMX) return RNMX; + else return temp; +} +#undef IA +#undef IM +#undef AM +#undef IQ +#undef IR +#undef NTAB +#undef NDIV +#undef EPS +#undef RNMX + +/* Generate a N(0,1) r.v. */ +double gaussian(long *idum) +{ + static int iset=0; + static double gset; + double fac,r,v1,v2; + double ran1(); + if (iset == 0) { + do { + v1=2.0*ran1(idum)-1.0; + v2=2.0*ran1(idum)-1.0; + r=v1*v1+v2*v2; + } while (r >= 1.0 || r == 0.0); + fac=sqrt(-2.0*log(r)/r); + gset=v1*fac; + iset=1; + return v2*fac; + } else { + iset=0; + return gset; + } +} + +/* generate a random bit */ +int random_bit(long *idum) +{ + return((ran1(idum)<0.5) ? 0 : 1); +} diff --git a/lib/CPUs/MIPS/bsp/examples/random.h b/lib/CPUs/MIPS/bsp/examples/random.h new file mode 100644 index 0000000..673d6af --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/random.h @@ -0,0 +1,6 @@ +/* random.h */ + +/* functions provided by random.c */ +extern double ran1(long *idum); +extern double gaussian(long *idum); +extern int random_bit(long *idum); diff --git a/lib/CPUs/MIPS/bsp/examples/richards_benchmark.c b/lib/CPUs/MIPS/bsp/examples/richards_benchmark.c new file mode 100644 index 0000000..f1fdfd0 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/richards_benchmark.c @@ -0,0 +1,408 @@ + +/* C version of the systems programming language benchmark +** Author: M. J. Jordan Cambridge Computer Laboratory. +** +** Modified by: M. Richards, Nov 1996 +** to be ANSI C and runnable on 64 bit machines + other minor changes +** Modified by: M. Richards, 20 Oct 1998 +** made minor corrections to improve ANSI compliance (suggested +** by David Levine) +** +** Compile with, say +** +** gcc -o bench bench.c +** +** or +** +** gcc -o bench100 -Dbench100 bench.c (for a version that obeys +** the main loop 100x more often) +*/ + +#include +#include + +#ifdef SMALL_PROBLEM_SIZE +#define Count 1000*1000 +#define Qpktcountval 2326389 +#define Holdcountval 930555 +#else +#define Count 10000*1000 +#define Qpktcountval 23263894 +#define Holdcountval 9305557 +#endif + + +#define TRUE 1 +#define FALSE 0 +#define MAXINT 32767 + +#define BUFSIZE 3 +#define I_IDLE 1 +#define I_WORK 2 +#define I_HANDLERA 3 +#define I_HANDLERB 4 +#define I_DEVA 5 +#define I_DEVB 6 +#define PKTBIT 1 +#define WAITBIT 2 +#define HOLDBIT 4 +#define NOTPKTBIT !1 +#define NOTWAITBIT !2 +#define NOTHOLDBIT 0XFFFB + +#define S_RUN 0 +#define S_RUNPKT 1 +#define S_WAIT 2 +#define S_WAITPKT 3 +#define S_HOLD 4 +#define S_HOLDPKT 5 +#define S_HOLDWAIT 6 +#define S_HOLDWAITPKT 7 + +#define K_DEV 1000 +#define K_WORK 1001 + +struct packet +{ + struct packet *p_link; + int p_id; + int p_kind; + int p_a1; + char p_a2[4]; +}; + +struct task +{ + struct task *t_link; + int t_id; + int t_pri; + struct packet *t_wkq; + int t_state; + struct task *(*t_fn)(struct packet *); + long t_v1; + long t_v2; +}; + +char alphabet[28] = "0ABCDEFGHIJKLMNOPQRSTUVWXYZ"; +struct task *tasktab[11] = {0,0,0,0,0,0,0,0,0,0,0}; +struct task *tasklist = 0; +struct task *tcb; +long taskid; +long v1; +long v2; +int qpktcount = 0; +int holdcount = 0; +int tracing = 1; +int layout = 0; + +void append(struct packet *pkt, struct packet *ptr); + +void createtask(int id, + int pri, + struct packet *wkq, + int state, + struct task *(*fn)(struct packet *), + long v1, + long v2) +{ + struct task *t = (struct task *)malloc(sizeof(struct task)); + + tasktab[id] = t; + t->t_link = tasklist; + t->t_id = id; + t->t_pri = pri; + t->t_wkq = wkq; + t->t_state = state; + t->t_fn = fn; + t->t_v1 = v1; + t->t_v2 = v2; + tasklist = t; +} + +struct packet *pkt(struct packet *link, int id, int kind) +{ + int i; + struct packet *p = (struct packet *)malloc(sizeof(struct packet)); + + for (i=0; i<=BUFSIZE; i++) + p->p_a2[i] = 0; + + p->p_link = link; + p->p_id = id; + p->p_kind = kind; + p->p_a1 = 0; + + return (p); +} + +void trace(char a) +{ + if ( --layout <= 0 ) + { + printf("\n"); + layout = 50; + } + + printf("%c", a); +} + +void schedule() +{ + while ( tcb != 0 ) + { + struct packet *pkt; + struct task *newtcb; + + pkt=0; + + switch ( tcb->t_state ) + { + case S_WAITPKT: + pkt = tcb->t_wkq; + tcb->t_wkq = pkt->p_link; + tcb->t_state = tcb->t_wkq == 0 ? S_RUN : S_RUNPKT; + + case S_RUN: + case S_RUNPKT: + taskid = tcb->t_id; + v1 = tcb->t_v1; + v2 = tcb->t_v2; + if (tracing==TRUE) trace(taskid+'0'); + + newtcb = (*(tcb->t_fn))(pkt); + tcb->t_v1 = v1; + tcb->t_v2 = v2; + tcb = newtcb; + break; + + case S_WAIT: + case S_HOLD: + case S_HOLDPKT: + case S_HOLDWAIT: + case S_HOLDWAITPKT: + tcb = tcb->t_link; + break; + + default: + return; + } + } +} + +struct task *Wait(void) +{ + tcb->t_state |= WAITBIT; + return (tcb); +} + +struct task *holdself(void) +{ + ++holdcount; + tcb->t_state |= HOLDBIT; + return (tcb->t_link) ; +} + +struct task *findtcb(int id) +{ + struct task *t = 0; + + if (1<=id && id<=(long)10) + t = tasktab[id]; + if (t==0) printf("\nBad task id %d\n", id); + return(t); +} + +struct task *release(int id) +{ + struct task *t; + + t = findtcb(id); + if ( t==0 ) return (0); + + t->t_state &= NOTHOLDBIT; + if ( t->t_pri > tcb->t_pri ) return (t); + + return (tcb) ; +} + + +struct task *qpkt(struct packet *pkt) +{ + struct task *t; + + t = findtcb(pkt->p_id); + if (t==0) return (t); + + qpktcount++; + + pkt->p_link = 0; + pkt->p_id = taskid; + + if (t->t_wkq==0) + { + t->t_wkq = pkt; + t->t_state |= PKTBIT; + if (t->t_pri > tcb->t_pri) return (t); + } + else + { + append(pkt, (struct packet *)&(t->t_wkq)); + } + + return (tcb); +} + +struct task *idlefn(struct packet *pkt) +{ + --v2; + if ( v2==0 ) return ( holdself() ); + + if ( (v1&1) == 0 ) + { + v1 = ( v1>>1) & MAXINT; + return ( release(I_DEVA) ); + } + else + { + v1 = ( (v1>>1) & MAXINT) ^ 0XD008; + return ( release(I_DEVB) ); + } +} + +struct task *workfn(struct packet *pkt) +{ + if ( pkt==0 ) return ( Wait() ); + else + { + int i; + + v1 = I_HANDLERA + I_HANDLERB - v1; + pkt->p_id = v1; + + pkt->p_a1 = 0; + for (i=0; i<=BUFSIZE; i++) + { + v2++; + if ( v2 > 26 ) v2 = 1; + (pkt->p_a2)[i] = alphabet[v2]; + } + return ( qpkt(pkt) ); + } +} + +struct task *handlerfn(struct packet *pkt) +{ + if ( pkt!=0) append(pkt, + (struct packet *)(pkt->p_kind==K_WORK ? &v1 : &v2)); + + if ( v1!=0 ) + { + int count; + struct packet *workpkt = (struct packet *)v1; + count = workpkt->p_a1; + + if ( count > BUFSIZE ) + { + v1 = (long)(((struct packet *)v1)->p_link); + return ( qpkt(workpkt) ); + } + + if ( v2!=0 ) + { + struct packet *devpkt; + + devpkt = (struct packet *)v2; + v2 = (long)(((struct packet *)v2)->p_link); + devpkt->p_a1 = workpkt->p_a2[count]; + workpkt->p_a1 = count+1; + return( qpkt(devpkt) ); + } + } + return ( Wait() ); +} + +struct task *devfn(struct packet *pkt) +{ + if ( pkt==0 ) + { + if ( v1==0 ) return ( Wait() ); + pkt = (struct packet *)v1; + v1 = 0; + return ( qpkt(pkt) ); + } + else + { + v1 = (long)pkt; + if (tracing==TRUE) trace(pkt->p_a1); + return ( holdself() ); + } +} + +void append(struct packet *pkt, struct packet *ptr) +{ + pkt->p_link = 0; + + while ( ptr->p_link ) ptr = ptr->p_link; + + ptr->p_link = pkt; +} + +int main() +{ + struct packet *wkq = 0; + int retval; + + printf("Bench mark starting\n"); + + createtask(I_IDLE, 0, wkq, S_RUN, idlefn, 1, Count); + + wkq = pkt(0, 0, K_WORK); + wkq = pkt(wkq, 0, K_WORK); + + createtask(I_WORK, 1000, wkq, S_WAITPKT, workfn, I_HANDLERA, 0); + + wkq = pkt(0, I_DEVA, K_DEV); + wkq = pkt(wkq, I_DEVA, K_DEV); + wkq = pkt(wkq, I_DEVA, K_DEV); + + createtask(I_HANDLERA, 2000, wkq, S_WAITPKT, handlerfn, 0, 0); + + wkq = pkt(0, I_DEVB, K_DEV); + wkq = pkt(wkq, I_DEVB, K_DEV); + wkq = pkt(wkq, I_DEVB, K_DEV); + + createtask(I_HANDLERB, 3000, wkq, S_WAITPKT, handlerfn, 0, 0); + + wkq = 0; + createtask(I_DEVA, 4000, wkq, S_WAIT, devfn, 0, 0); + createtask(I_DEVB, 5000, wkq, S_WAIT, devfn, 0, 0); + + tcb = tasklist; + + qpktcount = holdcount = 0; + + printf("Starting\n"); + + tracing = FALSE; + layout = 0; + + schedule(); + + printf("finished\n"); + + printf("qpkt count = %d holdcount = %d\n", + qpktcount, holdcount); + + printf("These results are "); + if (qpktcount == Qpktcountval && holdcount == Holdcountval) { + printf("correct"); + retval = 0; + } else { + printf("incorrect"); + retval = 1; + } + + printf("\nend of run\n"); + return retval; +} + diff --git a/lib/CPUs/MIPS/bsp/examples/rmd160.c b/lib/CPUs/MIPS/bsp/examples/rmd160.c new file mode 100644 index 0000000..8b0f2c7 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/rmd160.c @@ -0,0 +1,294 @@ +/********************************************************************\ + * + * FILE: rmd160.c + * + * CONTENTS: A sample C-implementation of the RIPEMD-160 + * hash-function. + * TARGET: any computer with an ANSI C compiler + * + * AUTHOR: Antoon Bosselaers, ESAT-COSIC + * DATE: 1 March 1996 + * VERSION: 1.0 + * + * Copyright (c) Katholieke Universiteit Leuven + * 1996, All Rights Reserved + * + * Conditions for use of the RIPEMD-160 Software + * + * The RIPEMD-160 software is freely available for use under the terms and + * conditions described hereunder, which shall be deemed to be accepted by + * any user of the software and applicable on any use of the software: + * + * 1. K.U.Leuven Department of Electrical Engineering-ESAT/COSIC shall for + * all purposes be considered the owner of the RIPEMD-160 software and of + * all copyright, trade secret, patent or other intellectual property + * rights therein. + * 2. The RIPEMD-160 software is provided on an "as is" basis without + * warranty of any sort, express or implied. K.U.Leuven makes no + * representation that the use of the software will not infringe any + * patent or proprietary right of third parties. User will indemnify + * K.U.Leuven and hold K.U.Leuven harmless from any claims or liabilities + * which may arise as a result of its use of the software. In no + * circumstances K.U.Leuven R&D will be held liable for any deficiency, + * fault or other mishappening with regard to the use or performance of + * the software. + * 3. User agrees to give due credit to K.U.Leuven in scientific publications + * or communications in relation with the use of the RIPEMD-160 software + * as follows: RIPEMD-160 software written by Antoon Bosselaers, + * available at http://www.esat.kuleuven.be/~cosicart/ps/AB-9601/. + * +\********************************************************************/ + +/* header files */ +#include +#include +#include +#include "rmd160.h" + +/********************************************************************/ + +void MDinit(dword *MDbuf) +{ + MDbuf[0] = 0x67452301UL; + MDbuf[1] = 0xefcdab89UL; + MDbuf[2] = 0x98badcfeUL; + MDbuf[3] = 0x10325476UL; + MDbuf[4] = 0xc3d2e1f0UL; + + return; +} + +/********************************************************************/ + +void compress(dword *MDbuf, dword *X) +{ + dword aa = MDbuf[0], bb = MDbuf[1], cc = MDbuf[2], + dd = MDbuf[3], ee = MDbuf[4]; + dword aaa = MDbuf[0], bbb = MDbuf[1], ccc = MDbuf[2], + ddd = MDbuf[3], eee = MDbuf[4]; + + /* round 1 */ + FF(aa, bb, cc, dd, ee, X[ 0], 11); + FF(ee, aa, bb, cc, dd, X[ 1], 14); + FF(dd, ee, aa, bb, cc, X[ 2], 15); + FF(cc, dd, ee, aa, bb, X[ 3], 12); + FF(bb, cc, dd, ee, aa, X[ 4], 5); + FF(aa, bb, cc, dd, ee, X[ 5], 8); + FF(ee, aa, bb, cc, dd, X[ 6], 7); + FF(dd, ee, aa, bb, cc, X[ 7], 9); + FF(cc, dd, ee, aa, bb, X[ 8], 11); + FF(bb, cc, dd, ee, aa, X[ 9], 13); + FF(aa, bb, cc, dd, ee, X[10], 14); + FF(ee, aa, bb, cc, dd, X[11], 15); + FF(dd, ee, aa, bb, cc, X[12], 6); + FF(cc, dd, ee, aa, bb, X[13], 7); + FF(bb, cc, dd, ee, aa, X[14], 9); + FF(aa, bb, cc, dd, ee, X[15], 8); + + /* round 2 */ + GG(ee, aa, bb, cc, dd, X[ 7], 7); + GG(dd, ee, aa, bb, cc, X[ 4], 6); + GG(cc, dd, ee, aa, bb, X[13], 8); + GG(bb, cc, dd, ee, aa, X[ 1], 13); + GG(aa, bb, cc, dd, ee, X[10], 11); + GG(ee, aa, bb, cc, dd, X[ 6], 9); + GG(dd, ee, aa, bb, cc, X[15], 7); + GG(cc, dd, ee, aa, bb, X[ 3], 15); + GG(bb, cc, dd, ee, aa, X[12], 7); + GG(aa, bb, cc, dd, ee, X[ 0], 12); + GG(ee, aa, bb, cc, dd, X[ 9], 15); + GG(dd, ee, aa, bb, cc, X[ 5], 9); + GG(cc, dd, ee, aa, bb, X[ 2], 11); + GG(bb, cc, dd, ee, aa, X[14], 7); + GG(aa, bb, cc, dd, ee, X[11], 13); + GG(ee, aa, bb, cc, dd, X[ 8], 12); + + /* round 3 */ + HH(dd, ee, aa, bb, cc, X[ 3], 11); + HH(cc, dd, ee, aa, bb, X[10], 13); + HH(bb, cc, dd, ee, aa, X[14], 6); + HH(aa, bb, cc, dd, ee, X[ 4], 7); + HH(ee, aa, bb, cc, dd, X[ 9], 14); + HH(dd, ee, aa, bb, cc, X[15], 9); + HH(cc, dd, ee, aa, bb, X[ 8], 13); + HH(bb, cc, dd, ee, aa, X[ 1], 15); + HH(aa, bb, cc, dd, ee, X[ 2], 14); + HH(ee, aa, bb, cc, dd, X[ 7], 8); + HH(dd, ee, aa, bb, cc, X[ 0], 13); + HH(cc, dd, ee, aa, bb, X[ 6], 6); + HH(bb, cc, dd, ee, aa, X[13], 5); + HH(aa, bb, cc, dd, ee, X[11], 12); + HH(ee, aa, bb, cc, dd, X[ 5], 7); + HH(dd, ee, aa, bb, cc, X[12], 5); + + /* round 4 */ + II(cc, dd, ee, aa, bb, X[ 1], 11); + II(bb, cc, dd, ee, aa, X[ 9], 12); + II(aa, bb, cc, dd, ee, X[11], 14); + II(ee, aa, bb, cc, dd, X[10], 15); + II(dd, ee, aa, bb, cc, X[ 0], 14); + II(cc, dd, ee, aa, bb, X[ 8], 15); + II(bb, cc, dd, ee, aa, X[12], 9); + II(aa, bb, cc, dd, ee, X[ 4], 8); + II(ee, aa, bb, cc, dd, X[13], 9); + II(dd, ee, aa, bb, cc, X[ 3], 14); + II(cc, dd, ee, aa, bb, X[ 7], 5); + II(bb, cc, dd, ee, aa, X[15], 6); + II(aa, bb, cc, dd, ee, X[14], 8); + II(ee, aa, bb, cc, dd, X[ 5], 6); + II(dd, ee, aa, bb, cc, X[ 6], 5); + II(cc, dd, ee, aa, bb, X[ 2], 12); + + /* round 5 */ + JJ(bb, cc, dd, ee, aa, X[ 4], 9); + JJ(aa, bb, cc, dd, ee, X[ 0], 15); + JJ(ee, aa, bb, cc, dd, X[ 5], 5); + JJ(dd, ee, aa, bb, cc, X[ 9], 11); + JJ(cc, dd, ee, aa, bb, X[ 7], 6); + JJ(bb, cc, dd, ee, aa, X[12], 8); + JJ(aa, bb, cc, dd, ee, X[ 2], 13); + JJ(ee, aa, bb, cc, dd, X[10], 12); + JJ(dd, ee, aa, bb, cc, X[14], 5); + JJ(cc, dd, ee, aa, bb, X[ 1], 12); + JJ(bb, cc, dd, ee, aa, X[ 3], 13); + JJ(aa, bb, cc, dd, ee, X[ 8], 14); + JJ(ee, aa, bb, cc, dd, X[11], 11); + JJ(dd, ee, aa, bb, cc, X[ 6], 8); + JJ(cc, dd, ee, aa, bb, X[15], 5); + JJ(bb, cc, dd, ee, aa, X[13], 6); + + /* parallel round 1 */ + JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8); + JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9); + JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9); + JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11); + JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13); + JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15); + JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15); + JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5); + JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7); + JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7); + JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8); + JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11); + JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14); + JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14); + JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12); + JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6); + + /* parallel round 2 */ + III(eee, aaa, bbb, ccc, ddd, X[ 6], 9); + III(ddd, eee, aaa, bbb, ccc, X[11], 13); + III(ccc, ddd, eee, aaa, bbb, X[ 3], 15); + III(bbb, ccc, ddd, eee, aaa, X[ 7], 7); + III(aaa, bbb, ccc, ddd, eee, X[ 0], 12); + III(eee, aaa, bbb, ccc, ddd, X[13], 8); + III(ddd, eee, aaa, bbb, ccc, X[ 5], 9); + III(ccc, ddd, eee, aaa, bbb, X[10], 11); + III(bbb, ccc, ddd, eee, aaa, X[14], 7); + III(aaa, bbb, ccc, ddd, eee, X[15], 7); + III(eee, aaa, bbb, ccc, ddd, X[ 8], 12); + III(ddd, eee, aaa, bbb, ccc, X[12], 7); + III(ccc, ddd, eee, aaa, bbb, X[ 4], 6); + III(bbb, ccc, ddd, eee, aaa, X[ 9], 15); + III(aaa, bbb, ccc, ddd, eee, X[ 1], 13); + III(eee, aaa, bbb, ccc, ddd, X[ 2], 11); + + /* parallel round 3 */ + HHH(ddd, eee, aaa, bbb, ccc, X[15], 9); + HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7); + HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15); + HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11); + HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8); + HHH(ddd, eee, aaa, bbb, ccc, X[14], 6); + HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6); + HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14); + HHH(aaa, bbb, ccc, ddd, eee, X[11], 12); + HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13); + HHH(ddd, eee, aaa, bbb, ccc, X[12], 5); + HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14); + HHH(bbb, ccc, ddd, eee, aaa, X[10], 13); + HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13); + HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7); + HHH(ddd, eee, aaa, bbb, ccc, X[13], 5); + + /* parallel round 4 */ + GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15); + GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5); + GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8); + GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11); + GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14); + GGG(ccc, ddd, eee, aaa, bbb, X[11], 14); + GGG(bbb, ccc, ddd, eee, aaa, X[15], 6); + GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14); + GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6); + GGG(ddd, eee, aaa, bbb, ccc, X[12], 9); + GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12); + GGG(bbb, ccc, ddd, eee, aaa, X[13], 9); + GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12); + GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5); + GGG(ddd, eee, aaa, bbb, ccc, X[10], 15); + GGG(ccc, ddd, eee, aaa, bbb, X[14], 8); + + /* parallel round 5 */ + FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8); + FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5); + FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12); + FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9); + FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12); + FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5); + FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14); + FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6); + FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8); + FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13); + FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6); + FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5); + FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15); + FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13); + FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11); + FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11); + + /* combine results */ + ddd += cc + MDbuf[1]; /* final result for MDbuf[0] */ + MDbuf[1] = MDbuf[2] + dd + eee; + MDbuf[2] = MDbuf[3] + ee + aaa; + MDbuf[3] = MDbuf[4] + aa + bbb; + MDbuf[4] = MDbuf[0] + bb + ccc; + MDbuf[0] = ddd; + + return; +} + +/********************************************************************/ + +void MDfinish(dword *MDbuf, byte *strptr, dword lswlen, dword mswlen) +{ + unsigned int i; /* counter */ + dword X[16]; /* message words */ + + memset(X, 0, 16*sizeof(dword)); + + /* put bytes from strptr into X */ + for (i=0; i<(lswlen&63); i++) { + /* byte i goes into word X[i div 4] at pos. 8*(i mod 4) */ + X[i>>2] ^= (dword) *strptr++ << (8 * (i&3)); + } + + /* append the bit m_n == 1 */ + X[(lswlen>>2)&15] ^= (dword)1 << (8*(lswlen&3) + 7); + + if ((lswlen & 63) > 55) { + /* length goes to next block */ + compress(MDbuf, X); + memset(X, 0, 16*sizeof(dword)); + } + + /* append length in bits*/ + X[14] = lswlen << 3; + X[15] = (lswlen >> 29) | (mswlen << 3); + compress(MDbuf, X); + + return; +} + +/************************ end of file rmd160.c **********************/ + diff --git a/lib/CPUs/MIPS/bsp/examples/rmd160.h b/lib/CPUs/MIPS/bsp/examples/rmd160.h new file mode 100644 index 0000000..70a33a6 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/rmd160.h @@ -0,0 +1,154 @@ +/********************************************************************\ + * + * FILE: rmd160.h + * + * CONTENTS: Header file for a sample C-implementation of the + * RIPEMD-160 hash-function. + * TARGET: any computer with an ANSI C compiler + * + * AUTHOR: Antoon Bosselaers, ESAT-COSIC + * DATE: 1 March 1996 + * VERSION: 1.0 + * + * Copyright (c) Katholieke Universiteit Leuven + * 1996, All Rights Reserved + * + * Conditions for use of the RIPEMD-160 Software + * + * The RIPEMD-160 software is freely available for use under the terms and + * conditions described hereunder, which shall be deemed to be accepted by + * any user of the software and applicable on any use of the software: + * + * 1. K.U.Leuven Department of Electrical Engineering-ESAT/COSIC shall for + * all purposes be considered the owner of the RIPEMD-160 software and of + * all copyright, trade secret, patent or other intellectual property + * rights therein. + * 2. The RIPEMD-160 software is provided on an "as is" basis without + * warranty of any sort, express or implied. K.U.Leuven makes no + * representation that the use of the software will not infringe any + * patent or proprietary right of third parties. User will indemnify + * K.U.Leuven and hold K.U.Leuven harmless from any claims or liabilities + * which may arise as a result of its use of the software. In no + * circumstances K.U.Leuven R&D will be held liable for any deficiency, + * fault or other mishappening with regard to the use or performance of + * the software. + * 3. User agrees to give due credit to K.U.Leuven in scientific publications + * or communications in relation with the use of the RIPEMD-160 software + * as follows: RIPEMD-160 software written by Antoon Bosselaers, + * available at http://www.esat.kuleuven.be/~cosicart/ps/AB-9601/. + * +\********************************************************************/ + +#ifndef RMD160H /* make sure this file is read only once */ +#define RMD160H + +/********************************************************************/ + +/* typedef 8 and 32 bit types, resp. */ +/* adapt these, if necessary, + for your operating system and compiler */ +typedef unsigned char byte; +typedef unsigned long dword; + + +/********************************************************************/ + +/* macro definitions */ + +/* collect four bytes into one word: */ +#define BYTES_TO_DWORD(strptr) \ + (((dword) *((strptr)+3) << 24) | \ + ((dword) *((strptr)+2) << 16) | \ + ((dword) *((strptr)+1) << 8) | \ + ((dword) *(strptr))) + +/* ROL(x, n) cyclically rotates x over n bits to the left */ +/* x must be of an unsigned 32 bits type and 0 <= n < 32. */ +#define ROL(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* the five basic functions F(), G() and H() */ +#define F(x, y, z) ((x) ^ (y) ^ (z)) +#define G(x, y, z) (((x) & (y)) | (~(x) & (z))) +#define H(x, y, z) (((x) | ~(y)) ^ (z)) +#define I(x, y, z) (((x) & (z)) | ((y) & ~(z))) +#define J(x, y, z) ((x) ^ ((y) | ~(z))) + +/* the ten basic operations FF() through III() */ +#define FF(a, b, c, d, e, x, s) {\ + (a) += F((b), (c), (d)) + (x);\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10);\ + } +#define GG(a, b, c, d, e, x, s) {\ + (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10);\ + } +#define HH(a, b, c, d, e, x, s) {\ + (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10);\ + } +#define II(a, b, c, d, e, x, s) {\ + (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10);\ + } +#define JJ(a, b, c, d, e, x, s) {\ + (a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10);\ + } +#define FFF(a, b, c, d, e, x, s) {\ + (a) += F((b), (c), (d)) + (x);\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10);\ + } +#define GGG(a, b, c, d, e, x, s) {\ + (a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10);\ + } +#define HHH(a, b, c, d, e, x, s) {\ + (a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10);\ + } +#define III(a, b, c, d, e, x, s) {\ + (a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10);\ + } +#define JJJ(a, b, c, d, e, x, s) {\ + (a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10);\ + } + +/********************************************************************/ + +/* function prototypes */ + +void MDinit(dword *MDbuf); +/* + * initializes MDbuffer to "magic constants" + */ + +void compress(dword *MDbuf, dword *X); +/* + * the compression function. + * transforms MDbuf using message bytes X[0] through X[15] + */ + +void MDfinish(dword *MDbuf, byte *strptr, dword lswlen, dword mswlen); +/* + * puts bytes from strptr into X and pad out; appends length + * and finally, compresses the last block(s) + * note: length in bits == 8 * (lswlen + 2^32 mswlen). + * note: there are (lswlen mod 64) bytes left in strptr. + */ + +#endif /* RMD160H */ + +/*********************** end of file rmd160.h ***********************/ + diff --git a/lib/CPUs/MIPS/bsp/examples/rmd160_test.c b/lib/CPUs/MIPS/bsp/examples/rmd160_test.c new file mode 100644 index 0000000..d46b86e --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/rmd160_test.c @@ -0,0 +1,113 @@ +#include +#include +#include +#include "libsys.h" + +#include "rmd160.h" + +#ifndef RMDsize +#define RMDsize 160 +#endif + +byte *RMD(byte *message) +/* + * returns RMD(message) + * message should be a string terminated by '\0' + */ +{ + dword MDbuf[RMDsize/32]; /* contains (A, B, C, D(, E)) */ + static byte hashcode[RMDsize/8]; /* for final hash-value */ + dword X[16]; /* current 16-word chunk */ + unsigned int i; /* counter */ + dword length; /* length in bytes of message */ + dword nbytes; /* # of bytes not yet processed */ + + /* initialize */ + MDinit(MDbuf); + length = (dword)strlen((char *)message); + + /* process message in 16-word chunks */ + for (nbytes=length; nbytes > 63; nbytes-=64) { + for (i=0; i<16; i++) { + X[i] = BYTES_TO_DWORD(message); + message += 4; + } + compress(MDbuf, X); + } /* length mod 64 bytes left */ + + /* finish: */ + MDfinish(MDbuf, message, length, 0); + + for (i=0; i>2]; /* implicit cast to byte */ + hashcode[i+1] = (MDbuf[i>>2] >> 8); /* extracts the 8 least */ + hashcode[i+2] = (MDbuf[i>>2] >> 16); /* significant bits. */ + hashcode[i+3] = (MDbuf[i>>2] >> 24); + } + + return (byte *)hashcode; +} + +#define MSG_SIZE (1*1024*1024) // Bit +#define TIME_STEP 2 + +char msg[MSG_SIZE/8+1]; +byte hashref[] = {0xFC,0x20,0x7B,0x84,0x40,0x1C,0x49,0x0B,0x8D,0x69,0x88,0xD2,0x49,0x20,0x01,0x90,0x41,0x77,0x72,0x59}; + +int main (void) +{ + int result, i, j, cnt; + byte *hashcode; + UINT32 start, stop; + + for (i=0; i < MSG_SIZE/8; i++) + msg[i] = 0x55; + + msg[i] = 0; + + setbuf(stdout, NULL); + + cnt = 0; + while(1) + { + while (start == time(NULL)); + + start = time(NULL); + stop = start + TIME_STEP; + + + while(1) + { + hashcode = RMD((byte *)msg); + cnt++; + + if (memcmp(hashcode, hashref, sizeof(hashref))) + { + printf("Error RipeMD-160!\n"); + printf("Hash expected: "); + for (i=0; i %d Mbit/s\n\n", cnt, MSG_SIZE/(1024*1024), TIME_STEP, cnt*MSG_SIZE/(1024*1024)/TIME_STEP); + cnt = 0; + break; + } + } + } + + return 0; +} + diff --git a/lib/CPUs/MIPS/bsp/examples/round.h b/lib/CPUs/MIPS/bsp/examples/round.h new file mode 100644 index 0000000..4dcbb58 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/round.h @@ -0,0 +1,55 @@ +/* +++Date last modified: 05-Jul-1997 */ + +/* +** rounding macros by Dave Knapp, Thad Smith, Jon Strayer, & Bob Stout +*/ + +#ifndef ROUND__H +#define ROUND__H + +#include + +#if defined(__cplusplus) && __cplusplus + +/* +** Safe C++ inline versions +*/ + +/* round to integer */ + +inline int iround(double x) +{ + return (int)floor(x + 0.5); +} + +/* round number n to d decimal points */ + +inline double fround(double n, unsigned d) +{ + return floor(n * pow(10., d) + .5) / pow(10., d); +} + +#else + +/* +** NOTE: These C macro versions are unsafe since arguments are referenced +** more than once. +** +** Avoid using these with expression arguments to be safe. +*/ + +/* +** round to integer +*/ + +#define iround(x) floor((x) + 0.5) + +/* +** round number n to d decimal points +*/ + +#define fround(n,d) (floor((n)*pow(10.,(d))+.5)/pow(10.,(d))) + +#endif + +#endif /* ROUND__H */ diff --git a/lib/CPUs/MIPS/bsp/examples/serdump.c b/lib/CPUs/MIPS/bsp/examples/serdump.c new file mode 100644 index 0000000..066d0ea --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/serdump.c @@ -0,0 +1,83 @@ +#include +#include +#include +#include +#include +#include +#include "libsys.h" + +#define BUF_SIZE 1024 +char buffer[BUF_SIZE]; +char rxbuf[BUF_SIZE]; +char * volatile pPtr_r; +char * volatile pPtr_w; +UINT32 volatile timeout_cnt; + +void handler3(void) +{ + volatile UINT32 *pUART_stat = (UINT32*)SYS_UART_STAT; + volatile UINT32 *pUART_data = (UINT32*)SYS_UART_DATA; + + while((0x10 & *pUART_stat)) + { +/// sputs("w: "); print_word((int)pPtr_w); sputs("\n"); + if (pPtr_w == &buffer[BUF_SIZE-1]) + pPtr_w = buffer; + *(pPtr_w++) = *pUART_data; + timeout_cnt = 200; + + } + +} + +int main(int argc, char **argv) +{ + volatile UINT32 *pUART_stat = (UINT32*)SYS_UART_STAT; + unsigned char *fileData; + unsigned long file_len, state; + + pPtr_r = buffer; + pPtr_w = buffer; + interrupt_register(3, handler3); + interrupt_enable(3); + *pUART_stat |= (1 << 6); + setbuf(stderr, NULL); + + state = 0; + while(1) + { + fprintf(stdout,"Reading serial stream..\n"); + file_len = 0; + timeout_cnt = 20000000; + while(timeout_cnt--) + { + sleep(1); + } + while(pPtr_w != pPtr_r) + { +// sputs("r: "); print_word((int)pPtr_r); sputs("\n"); + if (pPtr_r == &buffer[BUF_SIZE-1]) + pPtr_r = buffer; + rxbuf[file_len++] = *(pPtr_r++); + } + if (file_len) + { + PrintBuffer8(rxbuf, 16, file_len); + } + switch(state) + { + case 0: + if (!memcmp(rxbuf, "CLIENT", file_len)) + { + fprintf(stdout,"Send response\n"); + fprintf(stderr,"SERVER"); + state = 1; + } + break; + default: + break; + } + } + + return 0; +} diff --git a/lib/CPUs/MIPS/bsp/examples/snipmath.h b/lib/CPUs/MIPS/bsp/examples/snipmath.h new file mode 100644 index 0000000..9ef5841 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/snipmath.h @@ -0,0 +1,75 @@ +/* +++Date last modified: 05-Jul-1997 */ + +/* +** SNIPMATH.H - Header file for SNIPPETS math functions and macros +*/ + +#ifndef SNIPMATH__H +#define SNIPMATH__H + +#include +#include "sniptype.h" +#include "round.h" + +/* +** Callable library functions begin here +*/ + +void SetBCDLen(int n); /* Bcdl.C */ +long BCDtoLong(char *BCDNum); /* Bcdl.C */ +void LongtoBCD(long num, char BCDNum[]); /* Bcdl.C */ +double bcd_to_double(void *buf, size_t len, /* Bcdd.C */ + int digits); +int double_to_bcd(double arg, char *buf, /* Bcdd.C */ + size_t length, size_t digits ); +DWORD ncomb1 (int n, int m); /* Combin.C */ +DWORD ncomb2 (int n, int m); /* Combin.C */ +void SolveCubic(double a, double b, double c, /* Cubic.C */ + double d, int *solutions, + double *x); +DWORD dbl2ulong(double t); /* Dbl2Long.C */ +long dbl2long(double t); /* Dbl2Long.C */ +double dround(double x); /* Dblround.C */ + +/* Use #defines for Permutations and Combinations -- Factoryl.C */ + +#define log10P(n,r) (log10factorial(n)-log10factorial((n)-(r))) +#define log10C(n,r) (log10P((n),(r))-log10factorial(r)) + +double log10factorial(double N); /* Factoryl.C */ + +double fibo(unsigned short term); /* Fibo.C */ +double frandom(int n); /* Frand.C */ +double ipow(double x, int n); /* Ipow.C */ +int ispow2(int x); /* Ispow2.C */ +long double ldfloor(long double a); /* Ldfloor.C */ +int initlogscale(long dmax, long rmax); /* Logscale.C */ +long logscale(long d); /* Logscale.C */ + +float MSBINToIEEE(float f); /* Msb2Ieee.C */ +float IEEEToMSBIN(float f); /* Msb2Ieee.C */ +int perm_index (char pit[], int size); /* Perm_Idx.C */ +int round_div(int n, int d); /* Rnd_Div.C */ +long round_ldiv(long n, long d); /* Rnd_Div.C */ +double rad2deg(double rad); /* Rad2Deg.C */ +double deg2rad(double deg); /* Rad2Deg.C */ + +#include "pi.h" +#ifndef PHI + #define PHI ((1.0+sqrt(5.0))/2.0) /* the golden number */ + #define INV_PHI (1.0/PHI) /* the golden ratio */ +#endif + +/* +** File: ISQRT.C +*/ + +struct int_sqrt { + unsigned sqrt, + frac; +}; + +void usqrt(unsigned long x, struct int_sqrt *q); + + +#endif /* SNIPMATH__H */ diff --git a/lib/CPUs/MIPS/bsp/examples/sniptype.h b/lib/CPUs/MIPS/bsp/examples/sniptype.h new file mode 100644 index 0000000..399935d --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/sniptype.h @@ -0,0 +1,37 @@ +/* +++Date last modified: 05-Jul-1997 */ + +/* +** SNIPTYPE.H - Include file for SNIPPETS data types and commonly used macros +*/ + +#ifndef SNIPTYPE__H +#define SNIPTYPE__H + +#include /* For free() */ +#include /* For NULL & strlen() */ + +typedef enum {Error_ = -1, Success_, False_ = 0, True_} Boolean_T; + +/*#if !defined(WIN32) && !defined(_WIN32) && !defined(__NT__) \ + && !defined(_WINDOWS) + #if !defined(OS2)*/ + typedef unsigned char BYTE; + typedef unsigned long DWORD; +/* #endif*/ + typedef unsigned short WORD; +/*#else + #define WIN32_LEAN_AND_MEAN + #define NOGDI + #define NOSERVICE + #undef INC_OLE1 + #undef INC_OLE2 + #include + #define HUGE + #endif*/ + +#define NUL '\0' +#define LAST_CHAR(s) (((char *)s)[strlen(s) - 1]) +#define TOBOOL(x) (!(!(x))) +#define FREE(p) (free(p),(p)=NULL) + +#endif /* SNIPTYPE__H */ diff --git a/lib/CPUs/MIPS/bsp/examples/stanford.c b/lib/CPUs/MIPS/bsp/examples/stanford.c new file mode 100644 index 0000000..907477b --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/stanford.c @@ -0,0 +1,1117 @@ +/* stanford baby benchmark suite from john hennessy -- + +There are copies all around; the MIPS performance brief has up-to-date +numbers for a bunch of machines. BUT, these wouldn't be my first +choice. SPEC, the industry benchmark collection group, will probably +specify a new set of benchmarks shortly and release then right after +that. I imagine they will include espresso, gcc, and other large, but +public domain programs, for real things. + +here's bench.c + John Hennessy +*/ + + +/* This is a suite of benchmarks that are relatively short, both in program + size and execution time. It requires no input, and prints the execution + time for each program, using the system- dependent routine Getclock, + below, to find out the current CPU time. It does a rudimentary check to + make sure each program gets the right output. These programs were + gathered by John Hennessy and modified by Peter Nye. + +4.2 VERSION */ + +#include +#include +#include +#include + +#ifndef HZ +#define HZ 60 +#endif +#define nil 0 +#define false 0 +#define true 1 +#define bubblebase 1.61 +#define dnfbase 3.5 +#define permbase 1.75 +#define queensbase 1.83 +#define towersbase 2.39 +#define quickbase 1.92 +#define intmmbase 1.46 +#define treebase 2.5 +#define mmbase 0.0 +#define fpmmbase 2.92 +#define puzzlebase 0.5 +#define fftbase 0.0 +#define fpfftbase 4.44 + /* Towers */ +#define maxcells 18 + + /* Intmm, Mm */ +#define rowsize 40 + + /* Puzzle */ +#define size 511 +#define classmax 3 +#define typemax 12 +#define d 8 + + /* Bubble, Quick */ +#define sortelements 5000 +#define srtelements 500 + + /* fft */ +#define fftsize 256 +#define fftsize2 129 +/* +type */ + /* Perm */ +#define permrange 10 + + /* tree */ +struct node +{ + struct node *left, *right; + int val; +}; + +/* Towers *//* + discsizrange = 1..maxcells; */ +#define stackrange 3 +/* cellcursor = 0..maxcells; */ +struct element +{ + int discsize; + int next; +}; +/* emsgtype = packed array[1..15] of char; +*/ +/* Intmm, Mm *//* + index = 1 .. rowsize; + intmatrix = array [index,index] of integer; + realmatrix = array [index,index] of real; + */ +/* Puzzle *//* + piececlass = 0..classmax; + piecetype = 0..typemax; + position = 0..size; + */ +/* Bubble, Quick *//* + listsize = 0..sortelements; + sortarray = array [listsize] of integer; + */ + /* FFT */ +struct complex +{ + float rp, ip; +}; +/* + carray = array [1..fftsize] of complex ; + c2array = array [1..fftsize2] of complex ; +*/ + +float value; +float fixed, floated; + + /* global */ +int timer; +int xtimes[11]; +int seed; + + /* Perm */ +int permarray[permrange + 1]; +int pctr; + + /* tree */ +struct node *tree; + + /* Towers */ +int stack[stackrange + 1]; +struct element cellspace[maxcells + 1]; +int freelist, movesdone; + + /* Intmm, Mm */ +int ima[rowsize + 1][rowsize + 1], imb[rowsize + 1][rowsize + 1], + imr[rowsize + 1][rowsize + 1]; +float rma[rowsize + 1][rowsize + 1], rmb[rowsize + 1][rowsize + 1], + rmr[rowsize + 1][rowsize + 1]; + + /* Puzzle */ +int piececount[classmax + 1], + class[typemax + 1], + piecemax[typemax + 1], + puzzl[size + 1], p[typemax + 1][size + 1], n, kount; + + /* Bubble, Quick */ +int sortlist[sortelements + 1], biggest, littlest, top; + + /* FFT */ +struct complex z[fftsize + 1], w[fftsize + 1], e[fftsize2 + 1]; +float zr, zi; + +/* global procedures */ + +int +Getclock () +{ + struct tms rusage; + times (&rusage); + return ((60*rusage.tms_utime/HZ) * 50 / 3); +}; + +Initrand () +{ + seed = 74755; +}; + +int +Rand () +{ + seed = (seed * 1309 + 13849) & 65535; + return (seed); +}; + + + + /* Permutation program, heavily recursive, written by Denny Brown. */ + +Swap (a, b) + int *a, *b; +{ + int t; + t = *a; + *a = *b; + *b = t; +}; + +Initialize () +{ + int i; + for (i = 1; i <= 7; i++) + { + permarray[i] = i - 1; + }; +}; + +Permute (n) + int n; +{ /* permute */ + int k; + pctr = pctr + 1; + if (n != 1) + { + Permute (n - 1); + for (k = n - 1; k >= 1; k--) + { + Swap (&permarray[n], &permarray[k]); + Permute (n - 1); + Swap (&permarray[n], &permarray[k]); + }; + }; +} /* permute */ ; + +Perm () +{ /* Perm */ + int i; + pctr = 0; + for (i = 1; i <= 5; i++) + { + Initialize (); + Permute (7); + }; + if (pctr != 43300) + printf (" Error in Perm.\n"); +} /* Perm */ ; + + + + /* Program to Solve the Towers of Hanoi */ + +Error (emsg) + char *emsg; +{ + printf (" Error in Towers: %s\n", emsg); +}; + +Makenull (s) +{ + stack[s] = 0; +}; + +int +Getelement () +{ + int temp; + if (freelist > 0) + { + temp = freelist; + freelist = cellspace[freelist].next; + } + else + Error ("out of space "); + return (temp); +}; + +Push (i, s) + int i, s; +{ + int errorfound, localel; + errorfound = false; + if (stack[s] > 0) + if (cellspace[stack[s]].discsize <= i) + { + errorfound = true; + Error ("disc size error"); + }; + if (!errorfound) + { + localel = Getelement (); + cellspace[localel].next = stack[s]; + stack[s] = localel; + cellspace[localel].discsize = i; + } +}; + +Init (s, n) + int s, n; +{ + int discctr; + Makenull (s); + for (discctr = n; discctr >= 1; discctr--) + Push (discctr, s); +}; + +int +Pop (s) + int s; +{ + int temp, temp1; + if (stack[s] > 0) + { + temp1 = cellspace[stack[s]].discsize; + temp = cellspace[stack[s]].next; + cellspace[stack[s]].next = freelist; + freelist = stack[s]; + stack[s] = temp; + return (temp1); + } + else + Error ("nothing to pop "); +}; + +Move (s1, s2) + int s1, s2; +{ + Push (Pop (s1), s2); + movesdone = movesdone + 1; +}; + +tower (i, j, k) + int i, j, k; +{ + int other; + if (k == 1) + Move (i, j); + else + { + other = 6 - i - j; + tower (i, other, k - 1); + Move (i, j); + tower (other, j, k - 1); + } +}; + + +Towers () +{ /* Towers */ + int i; + for (i = 1; i <= maxcells; i++) + cellspace[i].next = i - 1; + freelist = maxcells; + Init (1, 14); + Makenull (2); + Makenull (3); + movesdone = 0; + tower (1, 2, 14); + if (movesdone != 16383) + printf (" Error in Towers.\n"); +}; /* Towers */ + + + /* The eight queens problem, solved 50 times. */ +/* + type + doubleboard = 2..16; + doublenorm = -7..7; + boardrange = 1..8; + aarray = array [boardrange] of boolean; + barray = array [doubleboard] of boolean; + carray = array [doublenorm] of boolean; + xarray = array [boardrange] of boardrange; +*/ + +Try (i, q, a, b, c, x) + int i, *q, a[], b[], c[], x[]; +{ + int j; + j = 0; + *q = false; + while ((!*q) && (j != 8)) + { + j = j + 1; + *q = false; + if (b[j] && a[i + j] && c[i - j + 7]) + { + x[i] = j; + b[j] = false; + a[i + j] = false; + c[i - j + 7] = false; + if (i < 8) + { + Try (i + 1, q, a, b, c, x); + if (!*q) + { + b[j] = true; + a[i + j] = true; + c[i - j + 7] = true; + } + } + else + *q = true; + } + } +}; + +Doit () +{ + int i, q; + int a[9], b[17], c[15], x[9]; + i = 0 - 7; + while (i <= 16) + { + if ((i >= 1) && (i <= 8)) + a[i] = true; + if (i >= 2) + b[i] = true; + if (i <= 7) + c[i + 7] = true; + i = i + 1; + }; + + Try (1, &q, b, a, c, x); + if (!q) + printf (" Error in Queens.\n"); +}; + +Queens () +{ + int i; + for (i = 1; i <= 50; i++) + Doit (); +}; + + /* Multiplies two integer matrices. */ + +Initmatrix (m) + int m[rowsize + 1][rowsize + 1]; +{ + int temp, i, j; + for (i = 1; i <= rowsize; i++) + for (j = 1; j <= rowsize; j++) + { + temp = Rand (); + m[i][j] = temp - (temp / 120) * 120 - 60; + } +}; + +Innerproduct (result, a, b, row, column) + int *result, a[rowsize + 1][rowsize + 1], b[rowsize + 1][rowsize + 1], + row, column; + /* computes the inner product of A[row,*] and B[*,column] */ +{ + int i; + *result = 0; + for (i = 1; i <= rowsize; i++) + *result = *result + a[row][i] * b[i][column]; +}; + +Intmm () +{ + int i, j; + Initrand (); + Initmatrix (ima); + Initmatrix (imb); + for (i = 1; i <= rowsize; i++) + for (j = 1; j <= rowsize; j++) + Innerproduct (&imr[i][j], ima, imb, i, j); +}; + + + /* Multiplies two real matrices. */ + +rInitmatrix (m) + float m[rowsize + 1][rowsize + 1]; +{ + int temp, i, j; + for (i = 1; i <= rowsize; i++) + for (j = 1; j <= rowsize; j++) + { + temp = Rand (); + m[i][j] = (temp - (temp / 120) * 120 - 60) / 3; + } +}; + +rInnerproduct (result, a, b, row, column) + float *result, a[rowsize + 1][rowsize + 1], b[rowsize + 1][rowsize + 1]; + int row, column; + /* computes the inner product of A[row,*] and B[*,column] */ +{ + int i; + *result = 0.0; + for (i = 1; i <= rowsize; i++) + *result = *result + a[row][i] * b[i][column]; +}; + +Mm () +{ + int i, j; + Initrand (); + rInitmatrix (rma); + rInitmatrix (rmb); + for (i = 1; i <= rowsize; i++) + for (j = 1; j <= rowsize; j++) + rInnerproduct (&rmr[i][j], rma, rmb, i, j); +}; + + + + + /* A compute-bound program from Forest Baskett. */ + +int +Fit (i, j) + int i, j; +{ + int k; + for (k = 0; k <= piecemax[i]; k++) + if (p[i][k]) + if (puzzl[j + k]) + return (false); + return (true); +}; + +int +Place (i, j) + int i, j; +{ + int k; + for (k = 0; k <= piecemax[i]; k++) + if (p[i][k]) + puzzl[j + k] = true; + piececount[class[i]] = piececount[class[i]] - 1; + for (k = j; k <= size; k++) + if (!puzzl[k]) + { + return (k); + }; + return (0); +}; + +Remove (i, j) + int i, j; +{ + int k; + for (k = 0; k <= piecemax[i]; k++) + if (p[i][k]) + puzzl[j + k] = false; + piececount[class[i]] = piececount[class[i]] + 1; +}; + +int +Trial (j) + int j; +{ + int i, k; + kount = kount + 1; + for (i = 0; i <= typemax; i++) + if (piececount[class[i]] != 0) + if (Fit (i, j)) + { + k = Place (i, j); + if (Trial (k) || (k == 0)) + { + return (true); + } + else + Remove (i, j); + }; + return (false); +}; + +Puzzle () +{ + int i, j, k, m; + for (m = 0; m <= size; m++) + puzzl[m] = true; + for (i = 1; i <= 5; i++) + for (j = 1; j <= 5; j++) + for (k = 1; k <= 5; k++) + puzzl[i + d * (j + d * k)] = false; + for (i = 0; i <= typemax; i++) + for (m = 0; m <= size; m++) + p[i][m] = false; + for (i = 0; i <= 3; i++) + for (j = 0; j <= 1; j++) + for (k = 0; k <= 0; k++) + p[0][i + d * (j + d * k)] = true; + class[0] = 0; + piecemax[0] = 3 + d * 1 + d * d * 0; + for (i = 0; i <= 1; i++) + for (j = 0; j <= 0; j++) + for (k = 0; k <= 3; k++) + p[1][i + d * (j + d * k)] = true; + class[1] = 0; + piecemax[1] = 1 + d * 0 + d * d * 3; + for (i = 0; i <= 0; i++) + for (j = 0; j <= 3; j++) + for (k = 0; k <= 1; k++) + p[2][i + d * (j + d * k)] = true; + class[2] = 0; + piecemax[2] = 0 + d * 3 + d * d * 1; + for (i = 0; i <= 1; i++) + for (j = 0; j <= 3; j++) + for (k = 0; k <= 0; k++) + p[3][i + d * (j + d * k)] = true; + class[3] = 0; + piecemax[3] = 1 + d * 3 + d * d * 0; + for (i = 0; i <= 3; i++) + for (j = 0; j <= 0; j++) + for (k = 0; k <= 1; k++) + p[4][i + d * (j + d * k)] = true; + class[4] = 0; + piecemax[4] = 3 + d * 0 + d * d * 1; + for (i = 0; i <= 0; i++) + for (j = 0; j <= 1; j++) + for (k = 0; k <= 3; k++) + p[5][i + d * (j + d * k)] = true; + class[5] = 0; + piecemax[5] = 0 + d * 1 + d * d * 3; + for (i = 0; i <= 2; i++) + for (j = 0; j <= 0; j++) + for (k = 0; k <= 0; k++) + p[6][i + d * (j + d * k)] = true; + class[6] = 1; + piecemax[6] = 2 + d * 0 + d * d * 0; + for (i = 0; i <= 0; i++) + for (j = 0; j <= 2; j++) + for (k = 0; k <= 0; k++) + p[7][i + d * (j + d * k)] = true; + class[7] = 1; + piecemax[7] = 0 + d * 2 + d * d * 0; + for (i = 0; i <= 0; i++) + for (j = 0; j <= 0; j++) + for (k = 0; k <= 2; k++) + p[8][i + d * (j + d * k)] = true; + class[8] = 1; + piecemax[8] = 0 + d * 0 + d * d * 2; + for (i = 0; i <= 1; i++) + for (j = 0; j <= 1; j++) + for (k = 0; k <= 0; k++) + p[9][i + d * (j + d * k)] = true; + class[9] = 2; + piecemax[9] = 1 + d * 1 + d * d * 0; + for (i = 0; i <= 1; i++) + for (j = 0; j <= 0; j++) + for (k = 0; k <= 1; k++) + p[10][i + d * (j + d * k)] = true; + class[10] = 2; + piecemax[10] = 1 + d * 0 + d * d * 1; + for (i = 0; i <= 0; i++) + for (j = 0; j <= 1; j++) + for (k = 0; k <= 1; k++) + p[11][i + d * (j + d * k)] = true; + class[11] = 2; + piecemax[11] = 0 + d * 1 + d * d * 1; + for (i = 0; i <= 1; i++) + for (j = 0; j <= 1; j++) + for (k = 0; k <= 1; k++) + p[12][i + d * (j + d * k)] = true; + class[12] = 3; + piecemax[12] = 1 + d * 1 + d * d * 1; + piececount[0] = 13; + piececount[1] = 3; + piececount[2] = 1; + piececount[3] = 1; + m = 1 + d * (1 + d * 1); + kount = 0; + if (Fit (0, m)) + n = Place (0, m); + else + printf ("Error1 in Puzzle\n"); + if (!Trial (n)) + printf ("Error2 in Puzzle.\n"); + else if (kount != 2005) + printf ("Error3 in Puzzle.\n"); +}; + + + + /* Sorts an array using quicksort */ + +Initarr () +{ + int i, temp; + Initrand (); + biggest = 0; + littlest = 0; + for (i = 1; i <= sortelements; i++) + { + temp = Rand (); + sortlist[i] = temp - (temp / 100000) * 100000 - 50000; + + if (sortlist[i] > biggest) + biggest = sortlist[i]; + else if (sortlist[i] < littlest) + littlest = sortlist[i]; + }; +}; + +Quicksort (a, l, r) + int a[], l, r; + /* quicksort the array A from start to finish */ +{ + int i, j, x, w; + + i = l; + j = r; + x = a[(l + r) / 2]; + do + { + while (a[i] < x) + i = i + 1; + while (x < a[j]) + j = j - 1; + if (i <= j) + { + w = a[i]; + a[i] = a[j]; + a[j] = w; + i = i + 1; + j = j - 1; + } + } + while (i <= j); + if (l < j) + Quicksort (a, l, j); + if (i < r) + Quicksort (a, i, r); +}; + + +Quick () +{ + Initarr (); + Quicksort (sortlist, 1, sortelements); + if ((sortlist[1] != littlest) || (sortlist[sortelements] != biggest)) + { + printf (" Error in Quick.\n"); + } + +}; + + + /* Sorts an array using treesort */ + +tInitarr () +{ + int i, temp; + Initrand (); + biggest = 0; + littlest = 0; + for (i = 1; i <= sortelements; i++) + { + temp = Rand (); + sortlist[i] = temp - (temp / 100000) * 100000 - 50000; + if (sortlist[i] > biggest) + biggest = sortlist[i]; + else if (sortlist[i] < littlest) + littlest = sortlist[i]; + }; + +}; + +CreateNode (t, n) + struct node **t; + int n; +{ + *t = (struct node *) malloc (sizeof (struct node)); + (*t)->left = nil; + (*t)->right = nil; + (*t)->val = n; +}; + +Insert (n, t) + int n; + struct node *t; + /* insert n into tree */ +{ + if (n > t->val) + if (t->left == nil) + CreateNode (&t->left, n); + else + Insert (n, t->left); + else if (n < t->val) + if (t->right == nil) + CreateNode (&t->right, n); + else + Insert (n, t->right); +}; + +int +Checktree (p) + struct node *p; + /* check by inorder traversal */ +{ + int result; + result = true; + if (p->left != nil) + if (p->left->val <= p->val) + result = false; + else + result = Checktree (p->left) && result; + if (p->right != nil) + if (p->right->val >= p->val) + result = false; + else + result = Checktree (p->right) && result; + return (result); +}; /* checktree */ + +Trees () +{ + int i; + tInitarr (); + tree = (struct node *) malloc (sizeof (struct node)); + tree->left = nil; + tree->right = nil; + tree->val = sortlist[1]; + for (i = 2; i <= sortelements; i++) + Insert (sortlist[i], tree); + if (!Checktree (tree)) + printf (" Error in Tree.\n"); +}; + + + /* Sorts an array using bubblesort */ + +bInitarr () +{ + int i, temp; + Initrand (); + biggest = 0; + littlest = 0; + for (i = 1; i <= srtelements; i++) + { + temp = Rand (); + sortlist[i] = temp - (temp / 100000) * 100000 - 50000; + if (sortlist[i] > biggest) + biggest = sortlist[i]; + else if (sortlist[i] < littlest) + littlest = sortlist[i]; + }; +}; + +Bubble () +{ + int i, j; + bInitarr (); + top = srtelements; + + while (top > 1) + { + + i = 1; + while (i < top) + { + + if (sortlist[i] > sortlist[i + 1]) + { + j = sortlist[i]; + sortlist[i] = sortlist[i + 1]; + sortlist[i + 1] = j; + }; + i = i + 1; + }; + + top = top - 1; + }; + if ((sortlist[1] != littlest) || (sortlist[srtelements] != biggest)) + printf ("Error3 in Bubble.\n"); +}; + + +float +Cos (x) + float x; +/* computes cos of x (x in radians) by an expansion */ +{ + int i, factor; + float result, power; + + result = 1.0; + factor = 1; + power = x; + for (i = 2; i <= 10; i++) + { + factor = factor * i; + power = power * x; + if ((i & 1) == 0) + { + if ((i & 3) == 0) + result = result + power / factor; + else + result = result - power / factor; + }; + }; + return (result); +}; + +int +Min0 (arg1, arg2) + int arg1, arg2; +{ + if (arg1 < arg2) + return (arg1); + else + return (arg2); +}; + +Printcomplex (arg1, arg2, zarray, start, finish, increment) + int arg1, arg2, start, finish, increment; + struct complex zarray[]; +{ + int i; + printf ("\n"); + + i = start; + do + { + printf (" %15.3e%15.3e", zarray[i].rp, zarray[i].ip); + i = i + increment; + printf (" %15.3e%15.3e", zarray[i].rp, zarray[i].ip); + printf ("\n"); + i = i + increment; + } + while (i <= finish); + +}; + +Uniform11 (iy, yfl) + int iy; + float yfl; +{ + iy = (4855 * iy + 1731) & 8191; + yfl = iy / 8192.0; +} /* uniform */ ; + +Exptab (n, e) + int n; + struct complex e[]; + +{ /* exptab */ + float theta, divisor, h[26]; + int i, j, k, l, m; + + theta = 3.1415926536; + divisor = 4.0; + for (i = 1; i <= 25; i++) + { + h[i] = 1 / (2 * Cos (theta / divisor)); + divisor = divisor + divisor; + }; + + m = n / 2; + l = m / 2; + j = 1; + e[1].rp = 1.0; + e[1].ip = 0.0; + e[l + 1].rp = 0.0; + e[l + 1].ip = 1.0; + e[m + 1].rp = -1.0; + e[m + 1].ip = 0.0; + + do + { + i = l / 2; + k = i; + + do + { + e[k + 1].rp = h[j] * (e[k + i + 1].rp + e[k - i + 1].rp); + e[k + 1].ip = h[j] * (e[k + i + 1].ip + e[k - i + 1].ip); + k = k + l; + } + while (k <= m); + + j = Min0 (j + 1, 25); + l = i; + } + while (l > 1); + +} /* exptab */ ; + +Fft (n, z, w, e, sqrinv) + int n; + struct complex z[], w[]; + struct complex e[]; + float sqrinv; +{ + int i, j, k, l, m, index; + m = n / 2; + l = 1; + + do + { + k = 0; + j = l; + i = 1; + + do + { + + do + { + w[i + k].rp = z[i].rp + z[m + i].rp; + w[i + k].ip = z[i].ip + z[m + i].ip; + w[i + j].rp = e[k + 1].rp * (z[i].rp - z[i + m].rp) + - e[k + 1].ip * (z[i].ip - z[i + m].ip); + w[i + j].ip = e[k + 1].rp * (z[i].ip - z[i + m].ip) + + e[k + 1].ip * (z[i].rp - z[i + m].rp); + i = i + 1; + } + while (i <= j); + + k = j; + j = k + l; + } + while (j <= m); + + /*z = w ; */ index = 1; + do + { + z[index] = w[index]; + index = index + 1; + } + while (index <= n); + l = l + l; + } + while (l <= m); + + for (i = 1; i <= n; i++) + { + z[i].rp = sqrinv * z[i].rp; + z[i].ip = -sqrinv * z[i].ip; + }; + +}; + +Oscar () +{ /* oscar */ + int i; + Exptab (fftsize, e); + seed = 5767; + for (i = 1; i <= fftsize; i++) + { + Uniform11 (seed, zr); + Uniform11 (seed, zi); + z[i].rp = 20.0 * zr - 10.0; + z[i].ip = 20.0 * zi - 10.0; + }; + + + for (i = 1; i <= 20; i++) + { + Fft (fftsize, z, w, e, 0.0625); +// Printcomplex( 6, 99, z, 1, 256, 17 ); + }; +} /* oscar */ ; + +main () +{ + int i; + fixed = 0.0; + floated = 0.0; + printf ("Starting \n"); +/* rewrite (output); */ + setbuf(stdout, nil); + printf (" Perm"); + timer = Getclock (); + Perm (); + xtimes[1] = Getclock () - timer; + fixed = fixed + permbase * xtimes[1]; + floated = floated + permbase * xtimes[1]; + printf (" Towers"); + timer = Getclock (); + Towers (); + xtimes[2] = Getclock () - timer; + fixed = fixed + towersbase * xtimes[2]; + floated = floated + towersbase * xtimes[2]; + printf (" Queens"); + timer = Getclock (); + Queens (); + xtimes[3] = Getclock () - timer; + fixed = fixed + queensbase * xtimes[3]; + floated = floated + queensbase * xtimes[3]; + printf (" Intmm"); + timer = Getclock (); + Intmm (); + xtimes[4] = Getclock () - timer; + fixed = fixed + intmmbase * xtimes[4]; + floated = floated + intmmbase * xtimes[4]; + printf (" Mm"); + timer = Getclock (); + Mm (); + xtimes[5] = Getclock () - timer; + fixed = fixed + mmbase * xtimes[5]; + floated = floated + fpmmbase * xtimes[5]; + printf (" Puzzle"); + timer = Getclock (); + Puzzle (); + xtimes[6] = Getclock () - timer; + fixed = fixed + puzzlebase * xtimes[6]; + floated = floated + puzzlebase * xtimes[6]; + printf (" Quick"); + timer = Getclock (); + Quick (); + xtimes[7] = Getclock () - timer; + fixed = fixed + quickbase * xtimes[7]; + floated = floated + quickbase * xtimes[7]; + printf (" Bubble"); + timer = Getclock (); + Bubble (); + xtimes[8] = Getclock () - timer; + fixed = fixed + bubblebase * xtimes[8]; + floated = floated + bubblebase * xtimes[8]; + printf (" Tree"); + timer = Getclock (); + Trees (); + xtimes[9] = Getclock () - timer; + fixed = fixed + treebase * xtimes[9]; + floated = floated + treebase * xtimes[9]; + printf (" FFT"); + timer = Getclock (); + Oscar (); + xtimes[10] = Getclock () - timer; + fixed = fixed + fftbase * xtimes[10]; + floated = floated + fpfftbase * xtimes[10]; + printf ("\n"); + for (i = 1; i <= 10; i++) + printf ("%8d", xtimes[i]); + printf ("\n"); + /* compute composites */ + printf ("\n"); + printf ("Nonfloating point composite is %10.0f\n", fixed / 10.0); + printf ("\n"); + printf ("Floating point composite is %10.0f\n", floated / 10.0); +} diff --git a/lib/CPUs/MIPS/bsp/examples/test_ac97.c b/lib/CPUs/MIPS/bsp/examples/test_ac97.c new file mode 100644 index 0000000..12dce79 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/test_ac97.c @@ -0,0 +1,310 @@ +#include +#include +#include +#include +#include +#include "libsys.h" + +#define PI 3.1415926535897932384626433832795 +#define SAMPLE_RATE 48000 +#define BUF_SIZE (2*4800) +#define REC_BUF_SIZE (5*60*2*SAMPLE_RATE) + +INT32 *buffer; +INT32 *rec_buffer; +UINT32 buf_size; + +INT32 * volatile pPtr_r; +INT32 * volatile pPtr_w; +UINT32 gcnt, led_cnt; +volatile INT32 sample_left, sample_right; + +#define AC97_REG_RESET 0x00 +#define AC97_REG_VOLO_MST 0x02 +#define AC97_REG_VOLO_HP 0x04 +#define AC97_REG_VOLO_MONO 0x06 +#define AC97_REG_VOLI_BEEP 0x0A +#define AC97_REG_VOLI_PHONE 0x0C +#define AC97_REG_VOLI_MIC 0x0E +#define AC97_REG_VOLI_LINE 0x10 +#define AC97_REG_VOLI_CD 0x12 +#define AC97_REG_VOLI_VIDEO 0x14 +#define AC97_REG_VOLI_AUX 0x16 +#define AC97_REG_VOLI_PCM 0x18 +#define AC97_REG_REC_SRC 0x1A +#define AC97_REG_REC_GAIN 0x1C +#define AC97_REG_EXTCTRL 0x2A +#define AC97_REG_RATE_DAC 0x2C +#define AC97_REG_RATE_ADC 0x32 + +UINT32 ac97_status(UINT32 reg) +{ + UINT32 offset; + volatile UINT32 *pAC_stat = (UINT32*)SYS_AC97_STAT; + volatile UINT32 *pAC_stat_ac = (UINT32*)SYS_AC97_ACSTAT; + + offset = (reg & 0x7E); + + // Wait if previous command is still pending + while(*pAC_stat & 1); + + *(pAC_stat_ac + offset) = 0; + + // Wait for data valid + while(!(*pAC_stat & 2)); + + return *pAC_stat_ac; +} + +void ac97_ctrl(UINT32 reg, UINT16 value) +{ + UINT32 offset; + volatile UINT32 *pAC_stat = (UINT32*)SYS_AC97_STAT; + volatile UINT32 *pAC_ctrl_ac = (UINT32*)SYS_AC97_ACCTRL; + + offset = (reg & 0x7E); + + // Wait if previous command is still pending + while(*pAC_stat & 1); + + *(pAC_ctrl_ac + offset) = value; + +} + +void ac97_isr_rec(void) +{ + int i, size; + volatile UINT32 *pReg = (UINT32*)SYS_LED_PORT; + volatile UINT32 *pAC_stat = (UINT32*)SYS_AC97_STAT; + volatile INT32 *pAC_pcm = (INT32*)SYS_AC97_PCM; + + if (!gcnt) + { + gcnt = SAMPLE_RATE; + *pReg = led_cnt++; + } + gcnt--; + + *pPtr_w++ = pAC_pcm[3]; + if (pPtr_w == &buffer[buf_size]) + pPtr_w = buffer; + + *pPtr_w++ = pAC_pcm[4]; + if (pPtr_w == &buffer[buf_size]) + pPtr_w = buffer; + + CP0_TR_write(pAC_pcm[3]); + CP0_TR_write(pAC_pcm[4]); + +} + +void ac97_isr_play(void) +{ + int i, size; + volatile UINT32 *pReg = (UINT32*)SYS_LED_PORT; + volatile UINT32 *pAC_stat = (UINT32*)SYS_AC97_STAT; + volatile INT32 *pAC_pcm = (INT32*)SYS_AC97_PCM; + + if (!gcnt) + { + gcnt = SAMPLE_RATE; + *pReg = led_cnt++; + } + gcnt--; + + *pAC_pcm = *pPtr_r++; + if (pPtr_r == &buffer[buf_size]) + pPtr_r = buffer; +} + +void ac97_isr_pass(void) +{ + int i, size; + volatile UINT32 *pReg = (UINT32*)SYS_LED_PORT; + volatile UINT32 *pAC_stat = (UINT32*)SYS_AC97_STAT; + volatile INT32 *pAC_pcm = (INT32*)SYS_AC97_PCM; + + if (!gcnt) + { + gcnt = SAMPLE_RATE; + *pReg = led_cnt++; + } + gcnt--; + + if (*pAC_stat & 0x08) + { + +// CP0_TR_write(pAC_pcm[3]); +// CP0_TR_write(pAC_pcm[4]); + + *pPtr_w++ = pAC_pcm[3]; + if (pPtr_w == &buffer[buf_size]) + pPtr_w = buffer; + + *pPtr_w++ = pAC_pcm[4]; + if (pPtr_w == &buffer[buf_size]) + pPtr_w = buffer; + } + + if (pPtr_r != pPtr_w) + { + *pAC_pcm = *pPtr_r++; + if (pPtr_r == &buffer[buf_size]) + pPtr_r = buffer; + } + +} + +int main (void) +{ + int result, i, j; + volatile UINT32 *pReg = (UINT32*)SYS_LED_PORT; + volatile UINT32 *pGPIO1 = (UINT32*)SYS_GPIO1; + volatile UINT32 *pAC_ctrl = (UINT32*)SYS_AC97_CTRL; + volatile UINT32 *pAC_stat = (UINT32*)SYS_AC97_STAT; + volatile UINT32 *pAC_ctrl_ac = (UINT32*)SYS_AC97_ACCTRL; + volatile UINT32 *pAC_stat_ac = (UINT32*)SYS_AC97_ACSTAT; + volatile UINT32 *pAC_pcm = (UINT32*)SYS_AC97_PCM; + double phi, dphi, y, mean; + char sel, cmd; + char buf[1024]; + FILE *pFile = stdout; + +// setbuf(stderr, NULL); +// + fprintf(pFile, "AC-97 Test\n"); + fprintf(pFile, "Status : %8.8X\n", *pAC_ctrl); + + ac97_ctrl(AC97_REG_VOLO_MST, 0); + ac97_ctrl(AC97_REG_VOLO_HP, 0); + ac97_ctrl(AC97_REG_VOLI_LINE, 0x8808); + ac97_ctrl(AC97_REG_VOLI_PCM, 0x0808); + ac97_ctrl(AC97_REG_REC_SRC, 0x0404); + ac97_ctrl(AC97_REG_REC_GAIN, 0); + ac97_ctrl(AC97_REG_EXTCTRL, 1); + + ac97_ctrl(AC97_REG_RATE_DAC, SAMPLE_RATE); + ac97_ctrl(AC97_REG_RATE_ADC, SAMPLE_RATE); + + led_cnt = 0; + gcnt = SAMPLE_RATE; + + fprintf(pFile, "DAC-Rate : %d\n", ac97_status(AC97_REG_RATE_DAC)); + fprintf(pFile, "ADC-Rate : %d\n", ac97_status(AC97_REG_RATE_ADC)); + + *pGPIO1 = 0x04; + + while(1) + { + fprintf(pFile, "Aufnehmen und Abspielen (1)\n"); + fprintf(pFile, "Sinus Ton (2)\n"); + fprintf(pFile, "Pass through (3)\n"); + fprintf(pFile, "Eingabe: "); + + scanf("%c", &sel); +// sel = 0x31; + + if (sel == 0x31) + { + buf_size = REC_BUF_SIZE; + buffer = (INT32*)malloc(REC_BUF_SIZE*sizeof(INT32)); +// memset(buffer, 0, sizeof(REC_BUF_SIZE*sizeof(INT32))); + pPtr_r = buffer; + pPtr_w = buffer; + + ac97_ctrl(AC97_REG_VOLI_LINE, 0x0808); + + cmd = 0; + while(1) + { + switch (cmd) + { + case 'r': + ac97_ctrl(AC97_REG_VOLI_LINE, 0x0808); + pPtr_w = buffer; + fprintf(pFile, "Aufnahme\n"); + interrupt_register(5, ac97_isr_rec); + interrupt_enable(5); + *pAC_ctrl = 0x24; + break; + + case 'p': + ac97_ctrl(AC97_REG_VOLI_LINE, 0x8808); + pPtr_r = buffer; + fprintf(pFile, "Wiedergabe\n"); + interrupt_register(5, ac97_isr_play); + interrupt_enable(5); + *pAC_ctrl = 0x12; + break; + + case ' ': + ac97_ctrl(AC97_REG_VOLI_LINE, 0x0808); + fprintf(pFile, "Stop\n"); + memset(buffer, 0, sizeof(REC_BUF_SIZE*sizeof(INT32))); + *pAC_ctrl = 0x00; + pPtr_r = buffer; + pPtr_w = buffer; + break; + + default: + fprintf(pFile, "Aufnahme (R)\n"); + fprintf(pFile, "Wiedergabe (P)\n"); + fprintf(pFile, "Stop (Space)\n"); + break; + } + cmd = readchar(0); + } + } + if (sel == 0x32) + { + buf_size = BUF_SIZE; + buffer = (INT32*)malloc(REC_BUF_SIZE*sizeof(INT32)); + memset(buffer, 0, sizeof(REC_BUF_SIZE*sizeof(INT32))); + pPtr_r = buffer; + pPtr_w = buffer; + + dphi = 120*2*PI/BUF_SIZE; + phi = 0; + for (i=0; i < BUF_SIZE/2; i++) + { + y = cos(phi); + buffer[2*i+0] = (INT32)(32000*y); + buffer[2*i+1] = (INT32)(32000*y); + phi = fmod((phi + dphi), 2.0*PI); + } + + fprintf(stderr, "Status : %8.8X\n", *pAC_ctrl); + + interrupt_register(5, ac97_isr_play); + interrupt_enable(5); + *pAC_ctrl = 0x12; + + fprintf(stderr, "Status : %8.8X\n", *pAC_ctrl); + + while(1) + { + fprintf(stderr, "Status : %8.8X\n", *pAC_ctrl); + } + } + if (sel == 0x33) + { + + buf_size = BUF_SIZE; + buffer = (INT32*)malloc(BUF_SIZE*sizeof(INT32)); + memset(buffer, 0, sizeof(BUF_SIZE*sizeof(INT32))); + pPtr_r = buffer; + pPtr_w = buffer; + *pAC_ctrl = 0x32; + interrupt_register(5, ac97_isr_pass); + interrupt_enable(5); + + fprintf(stdout, "Status : %8.8X\n", *pAC_ctrl); + + while(1); + } + } + + return 0; + +} + diff --git a/lib/CPUs/MIPS/bsp/examples/test_dcache.c b/lib/CPUs/MIPS/bsp/examples/test_dcache.c new file mode 100644 index 0000000..74327d1 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/test_dcache.c @@ -0,0 +1,61 @@ +#include +#include +#include "libsys.h" +#include "libsys.h" + +UINT32 tset(UINT32 *pMem) +{ + + __asm__ + ( + ".set noreorder\n" + ".set nomacro\n" + "addiu $t1, $0, 0x5555\n" + "lw $t0, 0(%[pMem])\n" + "sw $t1, 24(%[pMem])\n" + "addiu $t0, 8\n" + "sw $t0, 0(%[pMem])\n" + "nop\n" + "nop\n" + "nop\n" + "nop\n" + "nop\n" + "nop\n" + "nop\n" + "nop\n" + "nop\n" + "nop\n" + "nop\n" + "nop\n" + "lw $v0, 24(%[pMem])\n" + ".set macro\n" + ".set reorder\n" + : + : [pMem] "r" (pMem) + : "t0", "t1" + ); +} + +int main(void) +{ + int i; + volatile int *pLED = (int*)SYS_LED_PORT; + UINT64 *pBuf64; + UINT32 *pPtr; + + pBuf64 = (UINT64*)0x4000FC80; //malloc(1024*sizeof(UINT32)); + + pPtr = (UINT32*)pBuf64; + + for(i=0; i < 1024; i++) + *pPtr++ = i; + + pPtr = (UINT32*)pBuf64; + sputs("Ptr: "); print_word((int)pPtr); sputs("\n"); + DCACHE_invalidate_all(); + + + *pLED = tset(pPtr); + + return 0; +} diff --git a/lib/CPUs/MIPS/bsp/examples/test_endianess.c b/lib/CPUs/MIPS/bsp/examples/test_endianess.c new file mode 100644 index 0000000..8f0d737 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/test_endianess.c @@ -0,0 +1,64 @@ +#include +#include +#include +#include "libsys.h" + +#define TEST_SIZE 32768 +int main (void) +{ + int i; + UINT16 *ram16; + UINT32 sr; + UINT32 volatile *pReg = (UINT32*)SYS_LED_PORT; + + *pReg = 0; + + sr = CP0_SR_read(); + + ram16 = (UINT16*)calloc(TEST_SIZE/2,sizeof(UINT16)); + + CP0_SR_write(sr | (1 << 25)); + + for (i=0; i < TEST_SIZE/2; i++) + ram16[i] = (UINT16)i; + + for (i=TEST_SIZE/2-1; i >= 0; i--) + if (ram16[i] != (UINT16)i) + break; + + i++; + if (i) + *pReg = 0xFFFFFFFF; + else + *pReg = 1; + + + free(ram16); + + ram16 = (UINT16*)calloc(TEST_SIZE/2,sizeof(UINT16)); + + *pReg = 0; + CP0_SR_write(sr & ~(1 << 25)); + + for (i=0; i < TEST_SIZE/2; i++) + ram16[i] = (UINT16)i; + + for (i=TEST_SIZE/2-1; i >= 0; i--) + if (ram16[i] != (UINT16)i) + break; + + i++; + if (i) + *pReg = 0xFFFFFFFF; + else + *pReg = 1; + + + free(ram16); + + +// sputs("Status : ");print_word(sr);sputs("\n"); + + return 0; +} + diff --git a/lib/CPUs/MIPS/bsp/examples/test_exception.c b/lib/CPUs/MIPS/bsp/examples/test_exception.c new file mode 100644 index 0000000..34a0bca --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/test_exception.c @@ -0,0 +1,282 @@ +#include +#include +#include "libsys.h" + +void _exc_break(void) +{ + __asm + ( + ".set noreorder\n" + "break 0x9\n" + ".set reorder\n" + + ); +} + +void _exc_syscall(UINT32 code, UINT32 arg) +{ + __asm + ( + "move $v0, %[code]\n" + "move $a0, %[arg]\n" + "syscall\n" + : + : [code] "r" (code), [arg] "r" (arg) + : "v0", "a0" + + ); +} + +void _exc_arith(void) +{ + __asm + ( + ".set noreorder\n" + " li $t0, 0x7FFFFFFF\n" + " addi $t1, $t0, 2\n" + ".set reorder\n" + + ); +} + +void _exc_store_err(void) +{ + volatile int *pSrc = (int*)SYS_TIMER_SEC; + volatile int *pDst = (int*)0x40000001; + + *pDst = *pSrc; + +} + +void _exc_load_err(void) +{ + __asm + ( + ".set noreorder\n" + " li $t0, 0x40000000\n" + " li $t1, 0x40000000\n" + " lw $t1, 0($t1)\n" + " lw $t0, 2($t0)\n" + " lw $t1, 4($t0)\n" + "nop\n" + ".set reorder\n" + + ); + +} + +void _exc_kaddr_err(void) +{ + __asm + ( + ".set noreorder\n" + " li $t0, 0x80000000\n" + " jr $t0\n" + "nop\n" + ".set reorder\n" + + ); + +} + +void _exc_iaddr_daddr_err(void) +{ + __asm + ( + ".set noreorder\n" + " li $t0, 0x40000003\n" + " li $t1, 0x40000002\n" + " jr $t0\n" + " lw $t1, 0($t1)\n" + "nop\n" + ".set reorder\n" + + ); + +} + +void _exc_daddr_iaddr_err(void) +{ + __asm + ( + ".set noreorder\n" + " li $t0, 0x40000003\n" + " li $t1, 0x40000002\n" + " lw $t1, 0($t1)\n" + " jr $t0\n" + "nop\n" + ".set reorder\n" + + ); + +} + +void _exc_iaddr_err(void) +{ + __asm + ( + ".set noreorder\n" + " li $t0, 0x40000003\n" + " jr $t0\n" + "nop\n" + ".set reorder\n" + + ); + +} + +void _exc_ri(void) +{ + __asm + ( + ".set noreorder\n" + " li $t0, 0x40010000\n" + " li $t1, 0x9c563442\n" + " sw $t1, 0($t0)\n" + " jr $t0\n" + "nop\n" + ".set reorder\n" + + ); + +} + +void _exc_ibe(void) +{ + __asm + ( + ".set noreorder\n" + " li $t1, 0x10000000\n" + " jr $t1\n" + "nop\n" + ".set reorder\n" + + ); + +} + +void _exc_dbe(void) +{ + __asm + ( + ".set noreorder\n" + " li $t1, 0x10000000\n" + " lw $t0, 0($t1)\n" + "nop\n" + " jr $t0\n" + "nop\n" + ".set reorder\n" + + ); + +} + +void handler0(void) +{ + printf("Interrupt 0\n"); + interrupt_clr(0); +} + +void handler1(void) +{ + printf("Interrupt 1\n"); + interrupt_clr(1); +} + +int main(void) +{ + int buf[256]; + int i, sel; + + interrupt_register(0, handler0); + interrupt_enable(0); + interrupt_register(1, handler1); + interrupt_enable(1); + + while(1) + { + printf("Welche exception möchten Sie testen?\n"); + printf(" 1 : Reserved instruction\n"); + printf(" 2 : Privileged address (BadVAddr = 0x80000000)\n"); + printf(" 3 : Arithmetic overflow\n"); + printf(" 4 : Syscall\n"); + printf(" 5 : Breakpoint\n"); + printf(" 6 : Load error on instruction (BadVAddr = 0x40000003)\n"); + printf(" 7 : Load error on data (BadVAddr = 0x40000002)\n"); + printf(" 8 : Store error on data (BadVAddr = 0x40000001)\n"); + printf(" 9 : Bus error on instruction\n"); + printf("10 : Bus error on data\n"); + printf("11 : SW-interrupt 0\n"); + printf("12 : SW-interrupt 1\n"); + printf("13 : Load error on instruction and Load error on data (BadVAddr = 0x40000003)\n"); + printf("14 : Load error on data and Load error on instruction (BadVAddr = 0x40000002)\n"); + + scanf("%d", &sel); + printf("Jetzt kommt die exception (%d)!\n", sel); + + switch(sel) + { + case 1: + _exc_ri(); + break; + + case 2: + _exc_kaddr_err(); + break; + + case 3: + _exc_arith(); + break; + + case 4: + _exc_syscall(4, (UINT32)((char*)"Hallo Syscall (")); + _exc_syscall(1, 12345678); + _exc_syscall(4, (UINT32)((char*)")\n")); + break; + + case 5: + _exc_break(); + break; + + case 6: + _exc_iaddr_err(); + break; + + case 7: + _exc_load_err(); + break; + + case 8: + _exc_store_err(); + break; + + case 9: + printf("IBE: Exception not implemented in current CPU!\nPush reset to restart!\n"); + _exc_ibe(); + break; + + case 10: + printf("DBE: Exception not implemented in current CPU!\nPush reset to restart!\n"); + _exc_dbe(); + break; + + case 11: + case 12: + interrupt_set(sel-11); + break; + + case 13: + _exc_iaddr_daddr_err(); + break; + + case 14: + _exc_daddr_iaddr_err(); + break; + + default: + break; + } + sel = 0; + } + return 0; +} diff --git a/lib/CPUs/MIPS/bsp/examples/test_flash.c b/lib/CPUs/MIPS/bsp/examples/test_flash.c new file mode 100644 index 0000000..7d40961 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/test_flash.c @@ -0,0 +1,94 @@ +/************************************************************************/ +/* */ +/* AMD CFI Enabled Flash Memory Drivers */ +/* File name: CFIDRIVE.C */ +/* Revision: 1.0 5/07/98 */ +/* */ +/* Copyright (c) 1998 ADVANCED MICRO DEVICES, INC. All Rights Reserved. */ +/* This software is unpublished and contains the trade secrets and */ +/* confidential proprietary information of AMD. Unless otherwise */ +/* provided in the Software Agreement associated herewith, it is */ +/* licensed in confidence "AS IS" and is not to be reproduced in whole */ +/* or part by any means except for backup. Use, duplication, or */ +/* disclosure by the Government is subject to the restrictions in */ +/* paragraph (b) (3) (B) of the Rights in Technical Data and Computer */ +/* Software clause in DFAR 52.227-7013 (a) (Oct 1988). */ +/* Software owned by */ +/* Advanced Micro Devices, Inc., */ +/* One AMD Place, */ +/* P.O. Box 3453 */ +/* Sunnyvale, CA 94088-3453. */ +/************************************************************************/ +/* This software constitutes a basic shell of source code for */ +/* programming all AMD Flash components. AMD */ +/* will not be responsible for misuse or illegal use of this */ +/* software for devices not supported herein. AMD is providing */ +/* this source code "AS IS" and will not be responsible for */ +/* issues arising from incorrect user implementation of the */ +/* source code herein. It is the user's responsibility to */ +/* properly design-in this source code. */ +/* */ +/************************************************************************/ + +#include +#include +#include "cfiflash.h" +#include "libsys.h" + +#define TEST_SIZE (1024*1024) +#define FLASH_OFFSET 0x700000 +int main(void) +{ + int i; + flash_t flash; + UINT8 *pFlash = (UINT8*)0xA4000000; + UINT32 result; + UINT8 *pBuf; + + setbuf(stdout, NULL); + result = flash_find(&flash, 0xA4000000); + + if (result < 0) + { + printf("flash_find() error!\n"); + return 1; + } + + printf("Found Flash at %8.8X\n", (UINT32)flash.pBase); + + pBuf = (UINT8*)malloc(TEST_SIZE); + + for (i=0; i < TEST_SIZE; i++) + pBuf[i] = i; + + printf("Flash erase from %8.8X to %8.8X...", FLASH_OFFSET, FLASH_OFFSET+TEST_SIZE); + result = flash_erase(&flash, FLASH_OFFSET, TEST_SIZE); + if (result < 0) + { + printf("error!\n"); + return 1; + } + printf("OK\n"); + + printf("Flash program from %8.8X to %8.8X...", FLASH_OFFSET, FLASH_OFFSET+TEST_SIZE); + result = flash_program(&flash, FLASH_OFFSET, pBuf, TEST_SIZE); + if (result < 0) + { + printf("error!\n"); + return 1; + } + printf("OK\n"); + + printf("Flash verify from %8.8X to %8.8X...", FLASH_OFFSET, FLASH_OFFSET+TEST_SIZE); + result = flash_verify(&flash, FLASH_OFFSET, pBuf, TEST_SIZE); + if (result < 0) + { + printf("error!\n"); + return 1; + } + printf("OK\n"); + +// PrintBuffer8((UINT8*)pFlash, 16, TEST_SIZE); + + return 0; +} diff --git a/lib/CPUs/MIPS/bsp/examples/test_hpi.c b/lib/CPUs/MIPS/bsp/examples/test_hpi.c new file mode 100644 index 0000000..407d070 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/test_hpi.c @@ -0,0 +1,848 @@ +#include +#include +#include +#include +#include "libsys.h" +#include "cfiflash.h" +#include "hpi.h" + +static volatile UINT32 _g_uart_msg; +static volatile UINT32 _g_rst; +static volatile UINT32 _g_sus; +static volatile UINT32 _g_cfg; + +void uart_handler(void) +{ + volatile UINT32 *pUART_stat = (UINT32*)SYS_UART_STAT; + volatile UINT32 *pUART_data = (UINT32*)SYS_UART_DATA; + + while((SYS_PS2_BIT_RX_AVAIL & *pUART_stat)) + { + _g_uart_msg = *pUART_data; + } + +} + +void PrintDevRegs(UINT devid) +{ + int i; + UINT32 reg_base1, reg_base2, reg_addr; + + if ((devid < 1) || (devid > 2)) + return; + + printf("********************************************************\n"); + printf("Device %d status\n", devid); + printf("********************************************************\n"); + reg_base1 = 0x0200 + (devid-1)*0x80; + reg_base2 = 0xC080 + (devid-1)*0x20; + reg_addr = reg_base2 + 4; + printf("Port select (%4.4X) : %4.4X\n", reg_addr, hpi_read_reg(reg_addr)); + + reg_addr = reg_base2 + 10; + printf("USB control (%4.4X) : %4.4X\n", reg_addr, hpi_read_reg(reg_addr)); + + reg_addr = reg_base2 + 12; + printf("Int. enable (%4.4X) : %4.4X\n", reg_addr, hpi_read_reg(reg_addr)); + + reg_addr = reg_base2 + 14; + printf("Address (%4.4X) : %4.4X\n", reg_addr, hpi_read_reg(reg_addr)); + + reg_addr = reg_base2 + 16; + printf("Status (%4.4X) : %4.4X\n", reg_addr, hpi_read_reg(reg_addr)); + + reg_addr = reg_base2 + 18; + printf("Frame # reg (%4.4X) : %4.4X\n", reg_addr, hpi_read_reg(reg_addr)); + + reg_addr = reg_base2 + 20; + printf("SOF/EOP cnt (%4.4X) : %4.4X\n", reg_addr, hpi_read_reg(reg_addr)); + + for (i=0; i < 8; i++) + { + printf("EP# %d\n", i); + reg_addr = reg_base1 + 16*i + 0; + printf("Control (%4.4X) : %4.4X\n", reg_addr, hpi_read_reg(reg_addr)); + + reg_addr = reg_base1 + 16*i + 2; + printf("Address (%4.4X) : %4.4X\n", reg_addr, hpi_read_reg(reg_addr)); + + reg_addr = reg_base1 + 16*i + 4; + printf("Count (%4.4X) : %4.4X\n", reg_addr, hpi_read_reg(reg_addr)); + + reg_addr = reg_base1 + 16*i + 6; + printf("Status (%4.4X) : %4.4X\n", reg_addr, hpi_read_reg(reg_addr)); + + reg_addr = reg_base1 + 16*i + 8; + printf("Count result (%4.4X) : %4.4X\n", reg_addr, hpi_read_reg(reg_addr)); + + } +} + +typedef struct _sdev_descr_t +{ + UINT8 size; // length + UINT8 type; // desc type + UINT16 usb_spec; // USB spec + UINT8 devclass; // device class + UINT8 subclass; // sub class + UINT8 protocol; // protocol + UINT8 max_packet_size; // max packet size for endpoint 0 + UINT16 vendor_id; // Vendor ID + UINT16 product_id; // Product ID + UINT16 device_id; // device release number + UINT8 man_str_index; // index of manufacture string + UINT8 prod_str_index; // index of product string + UINT8 sn_str_index; // index of serial number string + UINT8 nconfs; // number of configurations +} __attribute__ ((__packed__)) dev_descr_t; + +typedef struct _sconf_descr_t +{ + UINT8 size; // length of this config + UINT8 type; // desc type + UINT16 total_size; // Total configuration desc length including this config and following descriptions + UINT8 nifaces; // Number of interface descriptions following this + UINT8 conf_id; // config number + UINT8 conf_str_index; // index of string describing config + UINT8 attr; // attributes (e.g. bus powered) + UINT8 current; // 2mA x (max. 250 => 500mA) +} __attribute__ ((__packed__)) conf_descr_t; + +typedef struct _siface_descr_t +{ + UINT8 size; // length of this config + UINT8 type; // desc type + UINT8 base; // base number + UINT8 alt; // alt + UINT8 neps; // number of endpoint description following this + UINT8 iface_class; // interface class (vendor) + UINT8 subclass; // subclass + UINT8 iface_proto; // interface proto (vendor) + UINT8 iface_str_index; +} __attribute__ ((__packed__)) iface_descr_t; + +typedef struct _sep_descr_t +{ + UINT8 size; // length of this config + UINT8 type; // type (endpoint) + UINT8 type_num; // type/number (Host use WriteFile) + UINT8 bulk; // Bulk + UINT16 pkt_size; // packet size + UINT8 interval; // interval +} __attribute__ ((__packed__)) ep_descr_t; + +typedef struct _sotg_descr_t +{ + UINT8 size; // length of this config + UINT8 type; // type (OTG) + UINT8 hnp_srp; // HNP|SRP support +} __attribute__ ((__packed__)) otg_descr_t; + +typedef struct _sstr_descr_hdr_t +{ + UINT8 size; // length of this config + UINT8 type; // type +} __attribute__ ((__packed__)) str_descr_hdr_t; + +typedef struct _scfg_inst_t +{ + usb_irp_t *pIRP_rx; + usb_irp_t *pIRP_tx; +} cfg_inst_t; + +UINT32 conf_write(UINT8 *pConfDescr, UINT32 neps, ep_descr_t *pEP) +{ + UINT32 pos, size; + conf_descr_t cfg; + iface_descr_t iface; + otg_descr_t otg_descr; + + // Fill config description + cfg.size = sizeof(conf_descr_t); + cfg.type = 2; + cfg.total_size = sizeof(conf_descr_t) + sizeof(iface_descr_t) + neps*sizeof(ep_descr_t) + sizeof(otg_descr_t); + cfg.nifaces = 1; // can handle only one interface per config + cfg.conf_id = 1; + cfg.conf_str_index = 0; + cfg.attr = 0x80; + cfg.current = 50; + + // Copy config description + pos = 0; + size = sizeof(conf_descr_t); + memcpy(&pConfDescr[pos], &cfg, size); + + // Fill interface description + iface.size = sizeof(iface_descr_t); + iface.type = 4; + iface.base = 0; + iface.alt = 0; + iface.neps = neps; + iface.iface_class = 0; + iface.subclass = 0; + iface.iface_proto = 0; + iface.iface_str_index = 0; + + // Copy interface description + pos += size; + size = sizeof(iface_descr_t); + memcpy(&pConfDescr[pos], &iface, size); + + // Copy N end point descriptions + pos += size; + size = neps*sizeof(ep_descr_t); + memcpy(&pConfDescr[pos], pEP, size); + + // Fill OTG description + otg_descr.size = sizeof(otg_descr_t); + otg_descr.type = 9; // OTG + otg_descr.hnp_srp = 3; // HNP|SRP supported + + // Copy OTG description + pos += size; + size = sizeof(ep_descr_t); + memcpy(&pConfDescr[pos], &otg_descr, size); + + pos += size; + + return pos; +} + +UINT32 str_write(UINT8 *pStrDescr, UINT8 *pStr0, UINT8 *pStr1, UINT8 *pStr2) +{ + int i; + UINT32 pos, size, strsize; + str_descr_hdr_t *pStrHdr; + UINT16 *pStr; + + pos = 0; + size = sizeof(str_descr_hdr_t); + strsize = 2; + pStrHdr = (str_descr_hdr_t*)&pStrDescr[pos]; + pStrHdr->size = size + strsize; + pStrHdr->type = 3; + + pos += size; + pStr = (UINT16*)&pStrDescr[pos]; + + *pStr = 0x0409; + + // String 0 + pos += size; + size = sizeof(str_descr_hdr_t); + strsize = strlen(pStr0); + + pStrHdr = (str_descr_hdr_t*)&pStrDescr[pos]; + pStrHdr->size = sizeof(str_descr_hdr_t) + 2*strsize; + pStrHdr->type = 3; + + pos += size; + size = 2*strsize; + pStr = (UINT16*)&pStrDescr[pos]; + + for (i=0; i < strsize; i++) + pStr[i] = (UINT16)pStr0[i]; + + // String 1 + pos += size; + size = sizeof(str_descr_hdr_t); + strsize = strlen(pStr1); + + pStrHdr = (str_descr_hdr_t*)&pStrDescr[pos]; + pStrHdr->size = sizeof(str_descr_hdr_t) + 2*strsize; + pStrHdr->type = 3; + + pos += size; + size = 2*strsize; + pStr = (UINT16*)&pStrDescr[pos]; + + for (i=0; i < strsize; i++) + pStr[i] = (UINT16)pStr1[i]; + + // String 2 + pos += size; + size = sizeof(str_descr_hdr_t); + strsize = strlen(pStr2); + + pStrHdr = (str_descr_hdr_t*)&pStrDescr[pos]; + pStrHdr->size = sizeof(str_descr_hdr_t) + 2*strsize; + pStrHdr->type = 3; + + pos += size; + size = 2*strsize; + pStr = (UINT16*)&pStrDescr[pos]; + + for (i=0; i < strsize; i++) + pStr[i] = (UINT16)pStr2[i]; + + pos += size; + + return pos; +} + +void ep0_func(void *pArg) +{ + UINT32 result; + UINT16 buf[USB_MAX_IMG_SIZE/2], ep_cntres, ep_status, ep_count, tsize; + usb_irp_t *pIRP = (usb_irp_t*)pArg; + +// printf("Callback with pArg = %8.8X\n", (UINT32)pArg); + ep_status = hpi_read_reg (SUSB2_REG_EP_STATUS0); + ep_cntres = hpi_read_reg (SUSB2_REG_EP_CNTRES0); + ep_count = hpi_read_reg (SUSB2_REG_EP_COUNT0); + + if (ep_status & 0x10) + { + printf("Setup-flag detected. Status = %4.4X\n", ep_status); + } +} + +void ep1_func(void *pArg) +{ + UINT32 result; + UINT16 buf[USB_MAX_IMG_SIZE/2], ep_cntres, ep_status, ep_count, tsize; + usb_irp_t *pIRP = (usb_irp_t*)pArg; + +// printf("Callback with pArg = %8.8X\n", (UINT32)pArg); + ep_status = hpi_read_reg (SUSB2_REG_EP_STATUS1); + ep_cntres = hpi_read_reg (SUSB2_REG_EP_CNTRES1); + ep_count = hpi_read_reg (SUSB2_REG_EP_COUNT1); + + tsize = pIRP->tsize; + if (ep_status & 0x0020) + { + printf("Length exception result %4.4X with count = %d\n", ep_status, (INT16)ep_cntres); + if (ep_status & 0x0400) + tsize = (UINT16)((INT16)tsize - (INT16)ep_cntres); + if (ep_status & 0x0800) + tsize = (UINT16)((INT16)tsize - (INT16)ep_cntres); + + } + result = hpi_read_ram(pIRP->cy_req.addr, buf, tsize); + usb_irp_enqueue(pIRP); + fifo_write(&pIRP->fifo, (UINT8*)buf, result, 0, FIFO_BLOCK); + +// printf("Read %d bytes\n", result); + +} + +void ep2_func(void *pArg) +{ + UINT32 result; + UINT16 buf[USB_MAX_IMG_SIZE/2], ep_cntres, ep_status, ep_count, tsize; + usb_irp_t *pIRP = (usb_irp_t*)pArg; + +// printf("Callback with pArg = %8.8X\n", (UINT32)pArg); + ep_status = hpi_read_reg (SUSB2_REG_EP_STATUS2); + ep_cntres = hpi_read_reg (SUSB2_REG_EP_CNTRES2); + ep_count = hpi_read_reg (SUSB2_REG_EP_COUNT2); + + tsize = pIRP->tsize; + if (ep_status & 0x0020) + { + printf("Length exception result %4.4X with count = %d\n", ep_status, (INT16)ep_cntres); + if (ep_status & 0x0400) + tsize = (UINT16)((INT16)tsize - (INT16)ep_cntres); + if (ep_status & 0x0800) + tsize = (UINT16)((INT16)tsize - (INT16)ep_cntres); + } + + pIRP->tx_in_progress = 0; + result = fifo_read(&pIRP->fifo, (UINT8*)buf, pIRP->tsize, 0, FIFO_NONBLOCK); + if (!result) + return; + + pIRP->cy_req.size = result; + hpi_write_ram(pIRP->cy_req.addr, (UINT16*)buf, result); + + usb_irp_enqueue(pIRP); + +// printf("Wrote %d bytes\n", result); + +} + +void rst_func(void *pArg) +{ + volatile int *pLED = (int*)SYS_LED_PORT; + +// printf("Callback with pArg = %8.8X\n", (UINT32)pArg); + sputs("SUSB_RST_MSG\n"); +/// hpi_comm_reset(); + + _g_rst = 1; + + *pLED = 0x40000000 + 1; + +} + +void sof_func(void *pArg) +{ + volatile int *pLED = (int*)SYS_LED_PORT; + +// printf("Callback with pArg = %8.8X\n", (UINT32)pArg); + sputs("SUSB_SOF_MSG\n"); + + *pLED = 0x40000000 + 2; + +} + +void cfg_func(void *pArg) +{ + volatile int *pLED = (int*)SYS_LED_PORT; + cfg_inst_t *pCFG = (cfg_inst_t*)pArg; + usb_irp_t *pIRP_rx = (usb_irp_t*)pCFG->pIRP_rx; + usb_irp_t *pIRP_tx = (usb_irp_t*)pCFG->pIRP_tx; + +// printf("Callback with pArg = %8.8X\n", (UINT32)pArg); + sputs("SUSB_CFG_MSG\n"); + _g_cfg = 1; + usb_irp_enqueue(pIRP_rx); + fifo_flush(&pIRP_rx->fifo); + fifo_flush(&pIRP_tx->fifo); + pIRP_tx->tx_in_progress = 0; + *pLED = 0; + +} + +void sus_func(void *pArg) +{ + volatile int *pLED = (int*)SYS_LED_PORT; + +// printf("Callback with pArg = %8.8X\n", (UINT32)pArg); + sputs("SUSB_SUS_MSG\n"); + + *pLED = 0x40000000 + 3; + + _g_sus = 1; + +} + +void id_func(void *pArg) +{ + volatile int *pLED = (int*)SYS_LED_PORT; + +// printf("Callback with pArg = %8.8X\n", (UINT32)pArg); + sputs("SUSB_ID_MSG\n"); + + *pLED = 0x40000000 + 4; + +} + +void vbus_func(void *pArg) +{ + volatile int *pLED = (int*)SYS_LED_PORT; + +// printf("Callback with pArg = %8.8X\n", (UINT32)pArg); + sputs("SUSB_VBUS_MSG\n"); + + *pLED = 0x40000000 + 5; + +} + +UINT32 usb_init_descr(void) +{ + UINT32 result; + + UINT16 buffer16[0x100]; + UINT16 addr; + dev_descr_t dev_descr = {sizeof(dev_descr_t), 1, 0x0200, 0xFF, 0, 0, 8, 0x04B4, 0x7200, 0x0099, 1, 2, 3, 1}; + ep_descr_t ep_descr[2] = {{sizeof(ep_descr_t), 5, 1, 2, 64, 0}, {sizeof(ep_descr_t), 5, 0x82, 2, 64, 0}}; + + // Set device descriptor + addr = 0xf516; // default + addr = 0xA00; + hpi_write_ram(addr, (UINT16*)&dev_descr, sizeof(dev_descr_t)); + hpi_write_reg(2*SUSB2_DEVICE_DESCRIPTOR_VEC, addr); + + // Set new configuration descriptor + + // Write config and interface descriptor + result = conf_write((UINT8*)buffer16, sizeof(ep_descr)/sizeof(ep_descr_t), ep_descr); + + addr = 0xf528; // default + addr = 0xB00; + hpi_write_ram(addr, (UINT16*)buffer16, result); + hpi_write_reg(2*SUSB2_CONFIGURATION_DESCRIPTOR_VEC, addr); + + // Set string description + result = str_write((UINT8*)buffer16, "JDI Inc.", "JDI-USB (MIPS)", "311070"); + addr = 0xf528; // default + addr = 0xC00; + hpi_write_ram(addr, (UINT16*)buffer16, result); + hpi_write_reg(2*SUSB2_STRING_DESCRIPTOR_VEC, addr); + + return 0; +} + +UINT32 usb_force_reconnect(UINT32 port) +{ + UINT32 result; + UINT16 addr; + + if (port >= USB_MAX_NUM_PORTS) + return -1; + + if (port == 0) + { + // R1 = 0 : Full speed + // R2 = 1 : SIE1 + addr = hpi_read_reg(SUSB1_REG_USBCTRL); + hpi_write_reg(SUSB1_REG_USBCTRL, addr | 0x0010); + result = hpi_comm_exec_int(SUSB_INIT_INT, 2, R1, 0, R2, 1); + hpi_write_reg(SUSB1_REG_USBCTRL, addr); + } + else + { + // R1 = 0 : Full speed + // R2 = 2 : SIE2 + addr = hpi_read_reg(SUSB2_REG_USBCTRL); + hpi_write_reg(SUSB2_REG_USBCTRL, addr | 0x0010); + result = hpi_comm_exec_int(SUSB_INIT_INT, 2, R1, 0, R2, 2); + hpi_write_reg(SUSB2_REG_USBCTRL, addr); + } + return result; +} + +UINT32 usb_recv(usb_irp_t *pObj, UINT8 *pData, UINT32 len, UINT32 timeout) +{ + UINT32 result; + + result = fifo_read(&pObj->fifo, pData, len, timeout, FIFO_BLOCK); + + return result; +} + +UINT32 usb_send(usb_irp_t *pObj, UINT8 *pData, UINT32 len, UINT32 timeout) +{ + UINT32 result; + UINT8 buf[USB_MAX_IMG_SIZE]; + + // Fill-up FIFO + result = fifo_write(&pObj->fifo, pData, len, 0, FIFO_NONBLOCK); + if (!result) + return 0; + + // Trigger TX + if (!pObj->tx_in_progress) + { + pObj->cy_req.size = fifo_read(&pObj->fifo, (UINT8*)buf, pObj->tsize, 0, FIFO_NONBLOCK); + hpi_write_ram(pObj->cy_req.addr, (UINT16*)buf, pObj->cy_req.size); + usb_irp_enqueue(pObj); + } + + // If necessary, write rest to FIFO + result += fifo_write(&pObj->fifo, &pData[result], len - result, timeout, FIFO_BLOCK); + + return result; + +} + +#define TEST_SIZE (2*1024*1024) +#define TRANSFER_SIZE 64 +#define FLASH_IMAGE_SIZE (2*1024*1024) + +int main(void) +{ + int i; + UINT32 result, sync, cmd, len, buf_count, led_count, remain, tx_cnt, flash_offset; + UINT8 buffer8[2048]; + UINT16 buffer16[0x2000]; + UINT16 addr; + volatile UINT32 *pLED = (UINT32*)SYS_LED_PORT; + volatile UINT32 *pUART0_stat = (UINT32*)SYS_UART0_STAT; + UINT32 start, end; + UINT32 *pFlash32; + UINT8 *pFlash8; + UINT32 buffer32[16], *pBuf; + UINT64 *pBuf64; + usb_irp_t irp_rx, irp_tx; + fifo_t fifo_rx, fifo_tx; + cfg_inst_t cfg_inst; + flash_t flash; + volatile UINT32 *pVGA_ctrl = (UINT32*)SYS_VGA_CTRL; + volatile UINT32 *pVGA_front = (UINT32*)SYS_VGA_FB_FRONT; + volatile UINT32 *pVGA_back = (UINT32*)SYS_VGA_FB_BACK; + + _g_rst = 0; + _g_sus = 0; + _g_cfg = 0; + + usb_init(); + + // enable EP#0 callback + usb_callback_register(1, SUSB_EP0_MSG, ep0_func, NULL); + + // enable EP#1 callback + usb_irp_register(&irp_rx, 1, 1, TRANSFER_SIZE, 1); + usb_callback_register(1, SUSB_EP1_MSG, ep1_func, &irp_rx); + + // enable EP#2 callback + usb_irp_register(&irp_tx, 1, 2, TRANSFER_SIZE, 0); + usb_callback_register(1, SUSB_EP2_MSG, ep2_func, &irp_tx); + + usb_callback_register(1, SUSB_RST_MSG, rst_func, NULL); + usb_callback_register(1, SUSB_SOF_MSG, sof_func, NULL); + cfg_inst.pIRP_rx = &irp_rx; + cfg_inst.pIRP_tx = &irp_tx; + usb_callback_register(1, SUSB_CFG_MSG, cfg_func, &cfg_inst); + usb_callback_register(1, SUSB_SUS_MSG, sus_func, NULL); + usb_callback_register(1, SUSB_ID_MSG, id_func, NULL); + usb_callback_register(1, SUSB_VBUS_MSG, vbus_func, NULL); + + printf("HPI-Test\n\n"); + + if (IS_ERROR(hpi_init())) + { + sputs("hpi_init(): error\n"); + return 1; + } + + printf("cy67k3_reset\n"); + cy67k3_reset(); + + while(!_g_rst); + + printf("hpi_comm_reset\n"); + hpi_comm_reset(); + + while(!_g_sus); + + printf("usb_init_descr\n"); + usb_init_descr(); + printf("hpi_comm_exec_int\n"); + hpi_comm_exec_int(SUSB_INIT_INT, 2, R1, 0, R2, 2); + printf("usb_force_reconnect\n"); + usb_force_reconnect(1); + + while(!_g_cfg); + + printf("USB-Ready\n"); + + printf("CY-Read.."); + start = clock(); + for (i=0; i < TEST_SIZE; i+=0x2000) + hpi_read_ram(0x2000, buffer16, 0x2000); + + end = clock(); + printf("done (%.2f Mbyte/s)\n", (double)TEST_SIZE/(1000*(end-start))); + + printf("CY-Write.."); + start = clock(); + for (i=0; i < TEST_SIZE; i+=0x2000) + hpi_write_ram(0x2000, buffer16, 0x2000); + + end = clock(); + printf("done (%.2f Mbyte/s)\n", (double)TEST_SIZE/(1000*(end-start))); + + sputs("HPI-Status : "); + print_word(cy67k3_read_HPI_STATUS()); + sputs("\n"); + + sputs("HPI BP : "); + print_word(hpi_read_reg(HPI_REG_BP)); + sputs("\n"); + + sputs("HPI IRR : "); + print_word(hpi_read_reg(HPI_REG_INTROUTE)); + sputs("\n"); + + sputs("CPU Revision : "); + print_word(hpi_comm_read_ctrl_reg(USB_REG_REVISON)); + sputs("\n"); + + hpi_comm_write_ctrl_reg(USB_REG_SPEED, 0x0000, LOGIC_DIRECT); + sputs("CPU Speed : "); + print_word(hpi_comm_read_ctrl_reg(USB_REG_SPEED)); + sputs("\n"); + +// usb_init_descr(); +// usb_force_reconnect(1); + + // enable RX interrupt + *pUART0_stat |= (1 << 6); + interrupt_register(3, uart_handler); + interrupt_enable(3); + + // Enable EP#1 + hpi_write_reg(SUSB2_REG_EP_COUNT1, TRANSFER_SIZE); + hpi_write_reg(SUSB2_REG_EP_CTRL1, 2); + hpi_write_reg(SUSB2_REG_EP_CNTRES1, 0); + hpi_write_reg(SUSB2_REG_EP_STATUS1, 0); + + // Enable EP#2 + hpi_write_reg(SUSB2_REG_EP_COUNT2, TRANSFER_SIZE); + hpi_write_reg(SUSB2_REG_EP_CTRL2, 2); + hpi_write_reg(SUSB2_REG_EP_CNTRES2, 0); + hpi_write_reg(SUSB2_REG_EP_STATUS2, 0); + + led_count = 0; + buf_count = 0; + + pBuf64 = (UINT64*)malloc(FLASH_IMAGE_SIZE); + pBuf = (UINT32*)pBuf64; + + *pVGA_front = (UINT32)pBuf64; + *pVGA_back = (UINT32)pBuf64; + *pVGA_ctrl |= SYS_VGA_BIT_MSTEN; + + if (IS_ERROR(flash_find(&flash, SYS_FLASH_IO))) + { + printf("Cannot find flash device. Exit now!\n"); + return 1; + } + + // Get flash offset by value of DIP-switch + flash_offset = flash_get_offset_by_blocknum(&flash, flash.info.nblocks-FLASH_IMAGE_SIZE/flash.info.blocksize); + printf("flash_offset: %08X\n", flash_offset); + pFlash32 = (UINT32*)(SYS_FLASH_IO + flash_offset); + pFlash8 = (UINT8*)pFlash32; + + while(1) + { + switch (_g_uart_msg) + { + case '1': + _g_uart_msg = 0; + PrintDevRegs(1); + printf("\nSIEmsg1: %4.4X\n", hpi_read_reg(HPI_REG_SIE1MSG)); + break; + + case '2': + _g_uart_msg = 0; + PrintDevRegs(2); + printf("\nSIEmsg2: %4.4X\n", hpi_read_reg(HPI_REG_SIE2MSG)); + break; + + default: + break; + } + result = usb_recv(&irp_rx, (UINT8*)&sync, 4, 100); + if (!result) + continue; + + *pLED = led_count++; + + if (sync == 0xC24755AA) + { + printf("Sync found\n"); + result = usb_recv(&irp_rx, (UINT8*)&cmd, 4, 1000); + if (!result) + continue; + + result = usb_recv(&irp_rx, (UINT8*)&len, 4, 1000); + if (!result) + continue; + + printf("Command %d with len %d found\n",cmd, len); + switch(cmd) + { + case 0x00000001: + result = usb_recv(&irp_rx, NULL, len, 1000); + if (result) + { + printf("Read %d bytes\n", result); + } + break; + + case 0x00000002: + remain = len; + tx_cnt = 0; + while(remain) + { + len = sizeof(buffer8); + if (remain < len) + len = remain; + + for (i=0; i < len; i++) + buffer8[i] = buf_count+i; + + result = usb_send(&irp_tx, buffer8, len, 1000); + if (!result) + break; + tx_cnt += result; + remain -= result; + buf_count++; + } + printf("Wrote %d bytes\n", tx_cnt); + break; + + case 0x00000003: + remain = len; + tx_cnt = 0; + while(remain) + { + len = 256; + if (remain < len) + len = remain; + + result = usb_send(&irp_tx, (UINT8*)&pFlash8[tx_cnt], len, 1000); + if (!result) + break; + tx_cnt += result; + remain -= result; + buf_count++; + } + printf("Wrote %d bytes\n", tx_cnt); + break; + + case 0x00000004: + *pVGA_ctrl &= ~SYS_VGA_BIT_MSTEN; + result = usb_recv(&irp_rx, (UINT8*)pBuf, len, 1000); + if (result) + { + printf("Read %d bytes\n", result); + } + + len = result; + if (len > FLASH_IMAGE_SIZE) + { + printf("Cannot write flash: image to large!\n"); + break; + } + + printf("Flash erase..."); + result = flash_erase(&flash, flash_offset, len); + if (IS_ERROR(result)) + { + printf("failed (%08X)\n", result); + break; + } + printf("done\n"); + + printf("Flash write..."); + result = flash_program(&flash, flash_offset, (UINT8*)pBuf, len); + if (IS_ERROR(result)) + { + printf("failed (%08X)\n", result); + break; + } + printf("done\n"); + + printf("Flash verify..."); + result = flash_verify(&flash, flash_offset, (UINT8*)pBuf, len); + if (IS_ERROR(result)) + { + printf("failed (%08X)\n", result); + break; + } + printf("passed\n"); + *pVGA_ctrl |= SYS_VGA_BIT_MSTEN; + break; + + case 0x000000FF: + usb_force_reconnect(1); + break; + + default: + break; + } + } + } + + return 0; +} + +// pMem = (UINT8*)0x40000000; +// result = fifo_write(&fifo_tx, pMem, 640, 0, FIFO_NONBLOCK); +// pMem += result; +// usb_irp_enqueue(&irp_tx); diff --git a/lib/CPUs/MIPS/bsp/examples/test_irq.c b/lib/CPUs/MIPS/bsp/examples/test_irq.c new file mode 100644 index 0000000..b1a9213 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/test_irq.c @@ -0,0 +1,335 @@ +#include +#include +#include +#include +#include +#include + +#define CPU_FREQ_HZ 100000000 +#include "libsys.h" +#include "irq.h" +#include "mips_gfx.h" +#include "mips_ps2.h" + +char buffer[16384]; +char * volatile pPtr_r; +char * volatile pPtr_w; +static volatile INT32 mouse_x; +static volatile INT32 mouse_y; +static box_t box; +static gfx_t gfx; +static volatile int _g_posx, _g_posy; +static volatile g_btn_l, g_btn_r; +static volatile UINT32 g_color; + +// ------------------------------------------------------------- +void handler0(void) +{ + printf("Interrupt 0\n"); + interrupt_clr(0); +} + +void handler1(void) +{ + printf("Interrupt 1\n"); + interrupt_clr(1); +} + +void handler2(void) +{ + printf("Interrupt 2\n"); +} + +void handler3(void) +{ + volatile UINT32 *pUART0_stat = (UINT32*)SYS_UART0_STAT; + volatile UINT32 *pUART0_data = (UINT32*)SYS_UART0_DATA; + volatile UINT32 *pUART1_stat = (UINT32*)SYS_UART1_STAT; + volatile UINT32 *pUART1_data = (UINT32*)SYS_UART1_DATA; + + while(0x200 & *pUART0_stat) + { +// sputs("w: "); print_word((int)pPtr_w); sputs("\n"); + if (pPtr_w == &buffer[16383]) + pPtr_w = buffer; + *(pPtr_w++) = *pUART0_data; + } + + while(0x200 & *pUART1_stat) + { +// sputs("w: "); print_word((int)pPtr_w); sputs("\n"); + if (pPtr_w == &buffer[16383]) + pPtr_w = buffer; + *(pPtr_w++) = *pUART1_data; + } + +} + +void handler4(void) +{ + printf("Interrupt 4\n"); +} + +void handler5(void) +{ + UINT32 volatile *pVGA_ctrl = (UINT32*)SYS_VGA_CTRL; + + // Ack + *pVGA_ctrl |= SYS_VGA_BIT_BUFCHG_FLAG; + +} + +void handler6(void) +{ + int p, i; + ps2_if_t *pIF; + UINT8 mouse_rsp[3]; + UINT32 timeout_count, key; + + INT32 dx, dy; + + for (p=0; p < PS2_get_num_if(); p++) + { + pIF = PS2_get_if(p); + if (SYS_PS2_BIT_RX_ERR_FLAG & *pIF->pCTRL) + fprintf(stderr, "PS2[%d]: Status = 0x%08X\n", p, *pIF->pCTRL); + + if (pIF->type == ps2_type_keyb) + { + while(SYS_PS2_BIT_RX_IRQ & *pIF->pCTRL) + { + key = *pIF->pDATA; + printf("Keyboard scan code = 0x%02X\n", key); + } + } + if (pIF->type == ps2_type_mouse) + { + if(!(SYS_PS2_BIT_RX_IRQ & *pIF->pCTRL)) + continue; + + for (i=0; i < 3; i++) + { + timeout_count = 100; + while(!(SYS_PS2_BIT_RX_IRQ & *pIF->pCTRL)) + { + timeout_count--; + if (!timeout_count) + { + break; + } + sleep(1); + } + if (!timeout_count) + { + break; + } + mouse_rsp[i] = (UINT8)*pIF->pDATA; + } + if (!timeout_count) + { + continue; + } + dx = mouse_rsp[1]; + if (mouse_rsp[0] & 0x10) + dx |= 0xFFFFFF00; + dy = mouse_rsp[2]; + if (mouse_rsp[0] & 0x20) + dy |= 0xFFFFFF00; + +// printf("dx = %5d, dy = %5d\n", dx, dy); + + mouse_x += dx; + mouse_y -= dy; + g_btn_l = 0; + if (mouse_rsp[0] & 0x01) + g_btn_l = 1; + + if (mouse_rsp[0] & 0x02) + { + if (g_btn_r == 0) + { + g_color = (UINT32)rand(); + } + g_btn_r = 1; + } + else + g_btn_r = 0; + + + if (mouse_x < 0) + mouse_x = 0; + if (mouse_y < 0) + mouse_y = 0; + if (mouse_x > (gfx.w-1)) + mouse_x = gfx.w-1; + if (mouse_y >= (gfx.h-1)) + mouse_y = gfx.h-1; + +// Screen_csr_set_x(mouse_x); +// Screen_csr_set_y(mouse_y); + +// printf("x = %5d, y = %5d\n", mouse_x, mouse_y); + + } + } +} + +void handler7(void) +{ + printf("Interrupt 7\n"); +} + +int main(void) +{ + + int i; + volatile UINT32 *pUART0_stat = (UINT32*)SYS_UART0_STAT; + volatile UINT32 *pUART1_stat = (UINT32*)SYS_UART1_STAT; + volatile UINT32 *pUART0_baud = (UINT32*)SYS_UART0_BAUD; + volatile UINT32 *pUART1_baud = (UINT32*)SYS_UART1_BAUD; + UINT32 volatile *pVGA_ctrl = (UINT32*)SYS_VGA_CTRL; + UINT32 volatile *pVGA_moffs_0 = (UINT32*)SYS_VGA_FB_FRONT; + UINT32 volatile *pVGA_moffs_1 = (UINT32*)SYS_VGA_FB_BACK; + UINT32 volatile *pVGA_cgcol = (UINT32*)SYS_VGA_CGCOL; + UINT32 volatile *pFlashPicture = (UINT32*)(SYS_FLASH_MEM + 0x00600000); + UINT32 framecount; + UINT32 start, end; + char string[65]; + + interrupt_register(0, (void*)handler0); + interrupt_register(1, (void*)handler1); +// interrupt_register(2, (void*)handler2); + interrupt_register(3, (void*)handler3); +// interrupt_register(4, (void*)handler4); +// interrupt_register(5, (void*)handler5); + interrupt_register(6, (void*)handler6); + interrupt_register(7, (void*)handler7); + + srand(clock()); + UART1_setbaud(460800); + printf("Hello\n"); + memset(buffer, 0, sizeof(buffer)); + + *pVGA_cgcol = 0x00FFFFFF; + _g_posx = _g_posy = 0; + g_color = 0xFFFFFFFF; + GFX_init(&gfx); + + GFX_set_background(&gfx, pFlashPicture, 800, 600, 1, 1); + box_create(&box, 256, 256); + GFX_box_draw(&gfx, &box, _g_posx, _g_posy, g_color); + GFX_show(&gfx); + printf("VGA status = %08X\n", *pVGA_ctrl); + + pPtr_r = buffer; + pPtr_w = buffer; + + printf("UART0 Status = 0x%8.8X\n", *pUART0_stat); + printf("UART0 Baud = 0x%8.8X\n", *pUART0_baud); + printf("UART1 Status = 0x%8.8X\n", *pUART1_stat); + printf("UART1 Baud = 0x%8.8X\n", *pUART1_baud); + + // UART: enable RX interrupt + *pUART0_stat |= (1 << 6); + *pUART1_stat |= (1 << 6); + printf("UART0 Status = 0x%8.8X\n", *pUART0_stat); + printf("UART1 Status = 0x%8.8X\n", *pUART1_stat); + + PS2_init(0); + PS2_init(1); + + sputs("r: "); print_word((int)pPtr_r); sputs("\n"); + sputs("w: "); print_word((int)pPtr_w); sputs("\n"); + + // Print Status register + sputs("Status : "); + print_word(CP0_SR_read()); + sputs("\n"); + sputs("\n"); + + interrupt_disable(6); + printf("Bitte gebe ein: "); + scanf("%s", string); + printf("Du schriebst: %s\n", string); + + // Flush buffer + PS2_flush(0); + PS2_flush(1); + + printf("Start:\n"); + + interrupt_enable(0); + interrupt_enable(1); +// interrupt_enable(2); + interrupt_enable(3); +// interrupt_enable(4); +// interrupt_enable(5); + interrupt_enable(6); + interrupt_enable(7); + + interrupt_set(0); + interrupt_set(1); + interrupt_set(2); + interrupt_set(3); + interrupt_set(4); + interrupt_set(5); + interrupt_set(6); + interrupt_set(7); + +// while(1) +// { +// printf("PS2-Status : 0x%08X\n", *(ps2_if[0].pCTRL)); +// printf("PS2-Data : 0x%08X\n", *(ps2_if[0].pDATA)); +// sleep(1000); +// } + + interrupt_enable(6); + framecount = Screen_get_fps(); + start = clock(); + + while(1) + { + if (!framecount) + { + end = clock(); + framecount = Screen_get_fps(); + printf("%f FPS\n", (float)framecount/((float)(end-start)/CLOCKS_PER_SEC)); + start = clock(); + } + + GFX_frame(&gfx, GFX_FRAME_SYNC); + framecount--; + + while ((_g_posx != (UINT32)mouse_x) || (_g_posy != (UINT32)mouse_y) || g_btn_r || g_btn_l) + { + + GFX_restore(&gfx, &box, _g_posx, _g_posy); + + _g_posx = (UINT32)mouse_x; + _g_posy = (UINT32)mouse_y; + + if (g_btn_l && !g_btn_r) + { + GFX_box_draw_bg(&gfx, &box, _g_posx, _g_posy, g_color); + } + + if (g_btn_l && g_btn_r) + { + GFX_set_background(&gfx, pFlashPicture, 800, 600, 1, 1); + } + + GFX_box_draw(&gfx, &box, _g_posx, _g_posy, g_color); + break; + } + GFX_show(&gfx); + + if(pPtr_w != pPtr_r) + { +// sputs("r: "); print_word((int)pPtr_r); sputs("\n"); + if (pPtr_r == &buffer[16383]) + pPtr_r = buffer; + writechar(0, *(pPtr_r++)); + } + } + return 0; +} diff --git a/lib/CPUs/MIPS/bsp/examples/test_mipsdis.c b/lib/CPUs/MIPS/bsp/examples/test_mipsdis.c new file mode 100644 index 0000000..eb3a61b --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/test_mipsdis.c @@ -0,0 +1,651 @@ +/* +----------------------------------------------------------------+ */ +/* | Copyright (c) 1994 Stanford University. | */ +/* | All Rights Reserved. | */ +/* | | */ +/* | This software is distributed with *ABSOLUTELY NO SUPPORT* | */ +/* | and *NO WARRANTY*. Use or reproduction of this code for | */ +/* | commerical gains is strictly prohibited. Otherwise, you | */ +/* | are given permission to use or modify this code as long | */ +/* | as you do not remove this notice. | */ +/* +----------------------------------------------------------------+ */ +/* --------------------------------------------------- */ +/* | Copyright (c) 1986 MIPS Computer Systems, Inc. | */ +/* | All Rights Reserved. | */ +/* --------------------------------------------------- */ + +/* + * Copyright 1985 by MIPS Computer Systems, Inc. + */ + +/* TORCH disassembler */ +/* derived from MIPS instruction dissassembler by PGL October 91 */ + +#include +#include +#include "mipsdis.h" + +#define false 0 +#define true 1 +typedef int boolean; +char *strcat(); + +#define ZERO 0 + +#define COMPILER_NAMES tdis_reg_names[0] +#define HARDWARE_NAMES tdis_reg_names[1] +#define ASSEMBLER_NAMES tdis_reg_names[2] +#define DIS_REG_NAMES(x) tdis_reg_names[x] + +union extension_byte { + unsigned char byte; + struct { /* extension byte bits in little-endian order */ +#if (defined __MIPSEB || defined _MIPSEB || defined MIPSEB) + unsigned reserved:1; + unsigned dyn_nop:1; + unsigned rs_boost:2; + unsigned rt_boost:2; + unsigned rd_boost:2; +#elif (defined __MIPSEL || defined _MIPSEL || defined MIPSEL) + unsigned rd_boost:2; + unsigned rt_boost:2; + unsigned rs_boost:2; + unsigned dyn_nop:1; + unsigned reserved:1; +#endif /*MIPSEB*/ + } e; +}; + +#define blez_op_T blez_op +#define blez_op_N (blez_op | 0x10) +#define bgtz_op_T bgtz_op +#define bgtz_op_N (bgtz_op | 0x10) +#define beq_op_T beq_op +#define beq_op_N (beq_op | 0x10) +#define bne_op_T bne_op +#define bne_op_N (bne_op | 0x10) +#define bc_op_T bc_op +#define bc_op_N (bc_op | 0x02) + +static char *op_name[64] = { +/* 0 */ "special", "regimm","j", "jal", "beq", "bne", "blez", "bgtz", +/* 8 */ "addi", "addiu","slti", "sltiu","andi", "ori", "xori", "lui", +/*16 */ "cop0", "cop1", "cop2", "cop3", "beql","bnel","blezl","bgtzl", +/*24 */ "op60", "op64", "op68", "op6c", "op70", "op74", "op78", "op7c", +/*32 */ "lb", "lh", "lwl", "lw", "lbu", "lhu", "lwr", "ld", +/*40 */ "sb", "sh", "swl", "sw", "opb0", "opb4", "swr", "sd", +/*48 */ "lwc0", "lwc1", "lwc2", "lwc3", "ldc0", "ldc1", "ldc2", "ldc3", +/*56 */ "swc0", "swc1", "swc2", "swc3", "sdc0", "sdc1", "sdc2", "sdc3" +}; + +static char *spec_name[64] = { +/* 0*/ "sll", "spec01","srl", "sra", "sllv", "spec05","srlv","srav", +/* 8*/ "jr", "jalr", "spec12","spec13","syscall","break","vcall","spec17", +/*16*/ "mfhi", "mthi", "mflo", "mtlo", "spec24","spec25","spec26","spec27", +/*24*/ "mult", "multu","div", "divu", "spec34","spec35","spec36","spec37", +/*32*/ "add", "addu", "sub", "subu", "and", "or", "xor", "nor", +/*40*/ "spec50","spec51","slt","sltu", "spec54","spec55","spec56","spec57", +/*48*/ "spec60","spec61","spec62","spec63","spec64","spec65","spec66","spec67", +/*56*/ "spec70","spec71","spec72","spec73","spec74","spec75","spec76","spec77" +}; + +static char *bcond_name[32] = { + "bltz", + "bgez", + "bltzl", + "bgezl", + "bcond04", + "bcond05", + "bcond06", + "bcond07", + "tgei", + "tgeiu", + "tlti", + "tltiu", + "teqi", + "bcond0d", + "tnei", + "bcond0f", + "bltzal", + "bgezal", + "bltzall", + "bgezall", + "bcond14", + "bcond15", + "bcond16", + "bcond17", + "bcond18", + "bcond19", + "bcond1a", + "bcond1b", + "bcond1c", + "bcond1d", + "bcond1e", + "bcond1f" +}; + +static char *cop1_name[64] = { +/* 0 */ "add", "sub", "mul", "div", "sqrt", "abs", "mov", "neg", +/* 8 */ "fop08","fop09","fop0a","fop0b","fop0c","fop0d","fop0e","fop0f", +/*16 */ "fop10","fop11","fop12","fop13","fop14","fop15","fop16","fop17", +/*24 */ "fop18","fop19","fop1a","fop1b","fop1c","fop1d","fop1e","fop1f", +/*32 */ "cvt.s","cvt.d","cvt.e","fop23","cvt.w","fop25","fop26","fop27", +/*40 */ "fop28","fop29","fop2a","fop2b","fop2c","fop2d","fop2e","fop2f", +/*48 */ "c.f", "c.un","c.eq","c.ueq","c.olt","c.ult","c.ole","c.ule", +/*56 */ "c.sf","c.ngle","c.seq","c.ngl","c.lt","c.nge","c.le","c.ngt" +}; + +static char *fmt_name[16] = { + "s", "d", "e", "q", + "w", "fmt5", "fmt6", "fmt7", + "fmt8", "fmt9", "fmta", "fmtb", + "fmtc", "fmtd", "fmte", "fmtf" +}; + +/* public */ +/* Three sets of commonly used register names */ +const char *tdis_reg_names[3][64] = { + { /* compiler names */ + "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", + "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", + "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", + "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", + "zero.B","at.B","v0.B", "v1.B", "a0.B", "a1.B", "a2.B", "a3.B", + "t0.B", "t1.B", "t2.B", "t3.B", "t4.B", "t5.B", "t6.B", "t7.B", + "s0.B", "s1.B", "s2.B", "s3.B", "s4.B", "s5.B", "s6.B", "s7.B", + "t8.B", "t9.B", "k0.B", "k1.B", "gp.B", "sp.B", "s8.B", "ra.B" + }, + { /* hardware names */ + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", + "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", + "r24", "r25", "r26", "r27", "gp", "sp", "r30", "r31", + "r0.B", "r1.B", "r2.B", "r3.B", "r4.B", "r5.B", "r6.B", "r7.B", + "r8.B", "r9.B", "r10.B","r11.B","r12.B","r13.B","r14.B","r15.B", + "r16.B","r17.B","r18.B","r19.B","r20.B","r21.B","r22.B","r23.B", + "r24.B","r25.B","r26.B","r27.B","gp.B", "sp.B", "r30.B","r31.B" + }, + { /* assembler names */ + "$0", "$at", "$2", "$3", "$4", "$5", "$6", "$7", + "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", + "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23", + "$24", "$25", "$26", "$27", "$gp", "$sp", "$30", "$31", + "$0.B", "$at.B","$2.B", "$3.B", "$4.B", "$5.B", "$6.B", "$7.B", + "$8.B", "$9.B", "$10.B","$11.B","$12.B","$13.B","$14.B","$15.B", + "$16.B","$17.B","$18.B","$19.B","$20.B","$21.B","$22.B","$23.B", + "$24.B","$25.B","$26.B","$27.B","$gp.B","$sp.B","$30.B","$31.B" + } +}; + +static char *c0_opname[64] = { + "c0op0","tlbr","tlbwi","c0op3","c0op4","c0op5","tlbwr","c0op7", + "tlbp","c0op9","c0op10","c0op11","c0op12","c0op13","c0op14","c0op15", + "rfe","c0op17","c0op18","c0op19","c0op20","c0op21","c0op22","c0op23", + "c0op24","c0op25","c0op26","c0op27","c0op28","c0op29","c0op30","c0op31", + "c0op32","c0op33","c0op34","c0op35","c0op36","c0op37","c0op38","c0op39", + "c0op40","c0op41","c0op42","c0op43","c0op44","c0op45","c0op46","c0op47", + "c0op48","c0op49","c0op50","c0op51","c0op52","c0op53","c0op54","c0op55", + "c0op56","c0op57","c0op58","c0op59","c0op60","c0op61","c0op62","c0op63" +}; + +static char *c0_reg[32] = { + "index","random","tlblo","c0r3","context","c0r5","c0r6","c0r7", + "badvaddr","c0r9","tlbhi","epcn","sr", "cause","epc", "c0r15", + "c0r16","c0r17","c0r18","c0r19","c0r20","c0r21","c0r22","c0r23", + "c0r24","c0r25","c0r26","c0r27","c0r28","c0r29","c0r30","c0r31" +}; + +/* Remember the options set by dis_init */ +#define ADDR_DEFAULT 0 +//#define ADDR_DEFAULT "%#010x:\t" +//#define VALUE_DEFAULT "%#010x\t" +#define VALUE_DEFAULT 0 +#define NAME_DEFAULT COMPILER_NAMES +static struct { + char *addr_format; + char *value_format; + const char **reg_names; + int print_jal_targets; +} save = { + ADDR_DEFAULT, + VALUE_DEFAULT, + NAME_DEFAULT, + true +}; + +/* Update regmask to reflect the use of this general-purpose (not fp) + register, and return its name */ +static const char * +register_name(ireg, boosted, regmask) +unsigned ireg, *regmask; +int boosted; +{ + if (!boosted) + *regmask |= (1 << ireg); + return save.reg_names[boosted ? ireg + 32 : ireg]; +} + +/* public -- see dissassembler.h */ +int +tdisasm(buffer, address, iword, ext, regmask, symbol_value, ls_register) +char *buffer; +unsigned char ext; /* extension byte */ +unsigned address, iword, *regmask, *symbol_value, *ls_register; +{ + int return_value = 0; + char *bufptr = buffer; + boolean do_b_displacement = false; + boolean do_loadstore = false; + union mips_instruction i; + union extension_byte e; + + *bufptr = 0; + i.word = iword; + e.byte = ext; + *regmask = *symbol_value = *ls_register = 0; + + /* Put out the address and hex value of the instruction, + leaving bufptr set at the end */ + if (save.addr_format) { + sprintf(bufptr, save.addr_format, address); + bufptr += strlen(bufptr); + } + if (save.value_format) { + sprintf(bufptr, save.value_format, iword); + bufptr += strlen(bufptr); + } + + /* check for dynamic NOP */ + if (e.e.dyn_nop) { + strcat(bufptr, "D."); + bufptr += 2; + } + + /* decode the instruction */ + switch (i.j_format.opcode) { + + case spec_op: + + if (i.word == 0x20) { + strcat(bufptr, "nop"); + if (e.e.rd_boost) + strcat(bufptr, ".B"); + bufptr += strlen(bufptr); + break; + } else if (i.r_format.func == addu_op && i.r_format.rt == ZERO) { + sprintf(bufptr, "move%s\t%s,%s", + e.e.rd_boost ? ".B" : "", + register_name(i.r_format.rd, e.e.rd_boost, regmask), + register_name(i.r_format.rs, e.e.rs_boost, regmask)); + bufptr += strlen(bufptr); + break; + } + strcat(bufptr, spec_name[i.r_format.func]); + if (e.e.rd_boost) + strcat(bufptr, ".B"); + bufptr += strlen(bufptr); + + switch (i.r_format.func) { + case sll_op: + case srl_op: + case sra_op: + sprintf(bufptr, "\t%s,%s,%d", + register_name(i.r_format.rd, e.e.rd_boost, regmask), + register_name(i.r_format.rt, e.e.rt_boost, regmask), + i.r_format.re); + break; + case sllv_op: + case srlv_op: + case srav_op: + sprintf(bufptr, "\t%s,%s,%s", + register_name(i.r_format.rd, e.e.rd_boost, regmask), + register_name(i.r_format.rt, e.e.rt_boost, regmask), + register_name(i.r_format.rs, e.e.rs_boost, regmask)); + break; + case mfhi_op: + case mflo_op: + sprintf(bufptr, "\t%s", + register_name(i.r_format.rd, e.e.rd_boost, regmask)); + break; + case jalr_op: + return_value = 2; + sprintf(bufptr, "\t%s,%s", + register_name(i.r_format.rd, e.e.rd_boost, regmask), + register_name(i.r_format.rs, e.e.rs_boost, regmask)); + break; + case jr_op: + return_value = 2; + /* fall through */ + case mtlo_op: + case mthi_op: + sprintf(bufptr, "\t%s", + register_name(i.r_format.rs, e.e.rs_boost, regmask)); + break; + case mult_op: + case multu_op: + case div_op: + case divu_op: + sprintf(bufptr, "\t%s,%s", + register_name(i.r_format.rs, e.e.rs_boost, regmask), + register_name(i.r_format.rt, e.e.rt_boost, regmask)); + break; + case syscall_op: + break; + case break_op: + case vcall_op: + { + char *format = "\t%d"; + unsigned op2 = i.r_format.rd * 32 + i.r_format.re; + + if (op2) + format = "\t%d,%d"; + sprintf(bufptr, format, i.r_format.rs*32+i.r_format.rt, + op2); + } + break; + default: + sprintf(bufptr, "\t%s,%s,%s", + register_name(i.r_format.rd, e.e.rd_boost, regmask), + register_name(i.r_format.rs, e.e.rs_boost, regmask), + register_name(i.r_format.rt, e.e.rt_boost, regmask)); + break; + }; + break; + + case bcond_op: + sprintf(bufptr, "%s%s\t%s,", + bcond_name[i.i_format.rt], + e.e.rd_boost ? ".B" : "", + register_name(i.i_format.rs, e.e.rs_boost, regmask)); + do_b_displacement = true; + break; + + case blez_op_T: + case bgtz_op_T: + case blez_op_N: + case bgtz_op_N: + sprintf(bufptr, "%s%s\t%s,", op_name[i.i_format.opcode], + e.e.rd_boost ? ".B" : "", + register_name(i.i_format.rs, e.e.rs_boost, regmask)); + do_b_displacement = true; + break; + case beq_op_T: + case beq_op_N: + if (i.i_format.rs == ZERO && i.i_format.rt == ZERO) { + strcat(bufptr, "b"); + if (i.j_format.opcode == beq_op_T) + strcat(bufptr, ".T"); + else + strcat(bufptr, ".N"); + if (e.e.rd_boost) + strcat(bufptr, ".B\t"); + else + strcat(bufptr, "\t"); + do_b_displacement = true; + break; + } + /* fall through */ + case bne_op_T: + case bne_op_N: + sprintf(bufptr, "%s%s\t%s,%s,", op_name[i.i_format.opcode], + e.e.rd_boost ? ".B" : "", + register_name(i.i_format.rs, e.e.rs_boost, regmask), + register_name(i.i_format.rt, e.e.rt_boost, regmask)); + do_b_displacement = true; + break; + + case cop0_op: + case cop1_op: + case cop2_op: + case cop3_op: + { + unsigned which_cop = i.j_format.opcode - cop0_op; + char *f_or_r = "rf"; + + switch (i.r_format.rs) { + case bc_op_T: + sprintf(bufptr, "bc%d%c.T%s\t", which_cop, + "ft"[i.r_format.rt], + e.e.rd_boost ? ".B" : ""); + do_b_displacement = true; + break; + case bc_op_N: + sprintf(bufptr, "bc%d%c.N%s\t", which_cop, + "ft"[i.r_format.rt], + e.e.rd_boost ? ".B" : ""); + do_b_displacement = true; + break; + case mtc_op: + if (which_cop == 0) + sprintf(bufptr, "mtc%d%s\t%s,%s", which_cop, + e.e.rd_boost ? ".B" : "", + register_name(i.r_format.rt, e.e.rt_boost,regmask), + c0_reg[i.f_format.rd]); + else + sprintf(bufptr, "mtc%d%s\t%s,%c%d", which_cop, + e.e.rd_boost ? ".B" : "", + register_name(i.r_format.rt, e.e.rt_boost,regmask), + f_or_r[(which_cop == 1)], + i.f_format.rd); + break; + case mfc_op: + if (which_cop == 0) + sprintf(bufptr, "mfc%d%s\t%s,%s", which_cop, + e.e.rd_boost ? ".B" : "", + register_name(i.r_format.rt, e.e.rt_boost,regmask), + c0_reg[i.f_format.rd]); + else + sprintf(bufptr, "mfc%d%s\t%s,%c%d", which_cop, + e.e.rd_boost ? ".B" : "", + register_name(i.r_format.rt, e.e.rt_boost,regmask), + f_or_r[(which_cop == 1)], + i.f_format.rd); + break; + case cfc_op: + sprintf(bufptr, "cfc%d%s\t%s,%c%d", which_cop, + e.e.rd_boost ? ".B" : "", + register_name(i.r_format.rt, e.e.rt_boost, regmask), + f_or_r[(which_cop == 1)], + i.f_format.rd); + break; + case ctc_op: + sprintf(bufptr, "ctc%d%s\t%s,%c%d", which_cop, + e.e.rd_boost ? ".B" : "", + register_name(i.r_format.rt, e.e.rt_boost, regmask), + f_or_r[(which_cop == 1)], + i.f_format.rd); + break; + default: + if (which_cop != 1) + sprintf(bufptr, "c0%s\t%s", e.e.rd_boost ? ".B" : "", + c0_opname[i.f_format.func]); + else + { + sprintf(bufptr, "%s.%s%s\t", + cop1_name[i.f_format.func], + fmt_name[i.f_format.fmt], + e.e.rd_boost ? ".B" : ""); + bufptr += strlen(bufptr); + switch (i.f_format.func) { + case fsqrt_op: + case fabs_op: + case fmov_op: + case fcvts_op: + case fcvtd_op: + case fcvte_op: + case fcvtw_op: + sprintf(bufptr, "f%d,f%d", + i.f_format.re, + i.f_format.rd); + break; + case fcmp_op+0x0: + case fcmp_op+0x1: + case fcmp_op+0x2: + case fcmp_op+0x3: + case fcmp_op+0x4: + case fcmp_op+0x5: + case fcmp_op+0x6: + case fcmp_op+0x7: + case fcmp_op+0x8: + case fcmp_op+0x9: + case fcmp_op+0xa: + case fcmp_op+0xb: + case fcmp_op+0xc: + case fcmp_op+0xd: + case fcmp_op+0xe: + case fcmp_op+0xf: + sprintf(bufptr, "f%d,f%d", + i.f_format.rd, + i.f_format.rt); + break; + default: + sprintf(bufptr, "f%d,f%d,f%d", + i.f_format.re, + i.f_format.rd, + i.f_format.rt); + break; + } /* switch on func */ + } + break; /* End of default */ + } /* switch on rs */ + } + break; /* End of cop0, cop1, cop2, cop3 */ + + case jal_op: + case j_op: + sprintf(bufptr, "%s%s\t", op_name[i.j_format.opcode], + e.e.rd_boost ? ".B" : ""); + *symbol_value = (address & 0xF0000000) | i.j_format.target << 2; + if (save.print_jal_targets) + { + bufptr += strlen(bufptr); + sprintf(bufptr, "%#x", *symbol_value); + } + return_value = 1; + break; + + case swc1_op: + case sdc1_op: + case lwc1_op: + case ldc1_op: + sprintf(bufptr, "%s%s\tf%d,", op_name[i.i_format.opcode], + e.e.rd_boost ? ".B" : "", + i.i_format.rt); + do_loadstore = true; + break; + + case lb_op: + case lh_op: + case lw_op: + case ld_op: + case lbu_op: + case lhu_op: + case sb_op: + case sh_op: + case sw_op: + case sd_op: + case lwl_op: + case lwr_op: + sprintf(bufptr, "%s%s\t%s,", op_name[i.i_format.opcode], + e.e.rd_boost ? ".B" : "", + register_name(i.i_format.rt, e.e.rt_boost, regmask)); + do_loadstore = true; + break; + + case ori_op: + case xori_op: + if (i.u_format.rs == ZERO) { + sprintf(bufptr, "li%s\t%s,%d", + e.e.rd_boost ? ".B" : "", + register_name(i.u_format.rt, e.e.rt_boost, regmask), + i.u_format.uimmediate); + break; + } + /* fall through */ + case andi_op: + sprintf(bufptr, "%s%s\t%s,%s,%#x", op_name[i.u_format.opcode], + e.e.rd_boost ? ".B" : "", + register_name(i.u_format.rt, e.e.rt_boost, regmask), + register_name(i.u_format.rs, e.e.rs_boost, regmask), + i.u_format.uimmediate); + break; + case lui_op: + sprintf(bufptr, "%s%s\t%s,%#x", op_name[i.u_format.opcode], + e.e.rd_boost ? ".B" : "", + register_name(i.u_format.rt, e.e.rt_boost, regmask), + i.u_format.uimmediate); + break; + case addi_op: + case addiu_op: + if (i.i_format.rs == ZERO) { + short sign_extender = i.i_format.simmediate; + sprintf(bufptr, "li%s\t%s,%d", + e.e.rd_boost ? ".B" : "", + register_name(i.i_format.rt, e.e.rt_boost, regmask), + sign_extender); + break; + } + /* fall through */ + default: + { + short sign_extender = i.i_format.simmediate; + sprintf(bufptr, "%s%s\t%s,%s,%d", op_name[i.i_format.opcode], + e.e.rd_boost ? ".B" : "", + register_name(i.i_format.rt, e.e.rt_boost, regmask), + register_name(i.i_format.rs, e.e.rs_boost, regmask), + sign_extender); + } + break; + } + + /* Some instructions require more than just registers */ + + if (do_loadstore) + { + short sign_extender = i.i_format.simmediate; + *symbol_value = sign_extender; + *ls_register = i.i_format.rs; + bufptr += strlen(bufptr); + sprintf(bufptr, "%d(%s)", sign_extender, + register_name(i.i_format.rs, e.e.rs_boost, regmask)); + return_value = -1; + } + else if (do_b_displacement) + { + short sign_extender = i.i_format.simmediate; + bufptr += strlen(bufptr); + sprintf(bufptr, "%#x", 4 + address + ((((long)sign_extender & 0xFFFD0000) | (0x3FFFF & (sign_extender << 2))))); +// sprintf(bufptr, "%#x", (long)sign_extender); + return_value = 2; + } + + return return_value; +} + +static long instrs[10]={ + 0x0411000a, + 0x03e0f021, + 0x02feb023, + 0x24010050, + 0x10360044, + 0x24010090, + 0x10360046, + 0x240100b8, + 0x10360048, + 0x240100d0 + }; + +int main(void) +{ + int i; + int junk; + char buf[80]; + long *pInstr = (long*)instrs; + + for (i=0; i < 10; i++) + { + tdisasm(buf, (long)&pInstr[i], pInstr[i], 0, &junk, &junk, &junk); + printf("%s\n", buf); + } + return 0; + +} diff --git a/lib/CPUs/MIPS/bsp/examples/test_timer.c b/lib/CPUs/MIPS/bsp/examples/test_timer.c new file mode 100644 index 0000000..91b5a78 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/test_timer.c @@ -0,0 +1,40 @@ +#include "libsys.h" + + +int g_cnt; +void handler7(void) +{ + UINT32 *pGPIO0 = (UINT32*)SYS_GPIO0; + UINT32 *pTim_stat = (UINT32*)SYS_ITIM_STAT; + if (*pTim_stat & 1) + { + *pTim_stat = 1; + *pGPIO0 = g_cnt++; + } + +} + +int main (void) +{ + UINT32 *pTim_ctrl = (UINT32*)SYS_ITIM_CTRL; + UINT32 *pTim_stat = (UINT32*)SYS_ITIM_STAT; + UINT32 *pTim_cnt = (UINT32*)SYS_ITIM_CNT; + UINT32 *pTim_cmp = (UINT32*)SYS_ITIM_CMP; + UINT32 *pGPIO0 = (UINT32*)SYS_GPIO0; + + g_cnt = 1; + *pGPIO0 = 0; + + interrupt_register(7, handler7); + interrupt_enable(7); + + *pTim_cnt = 0; + *pTim_cmp = 2000; + *pTim_stat = 1; + *pTim_ctrl = 3; + + while(1); + + return 0; +} + diff --git a/lib/CPUs/MIPS/bsp/examples/test_vga.c b/lib/CPUs/MIPS/bsp/examples/test_vga.c new file mode 100644 index 0000000..7919abd --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/test_vga.c @@ -0,0 +1,206 @@ +#include +#include +#include +#include +#include +#include + +#define CPU_FREQ_HZ 100000000 +#include "libsys.h" +#include "irq.h" +#include "mips_gfx.h" +#include "mips_ps2.h" + +static volatile INT32 mouse_x; +static volatile INT32 mouse_y; +static box_t box; +static gfx_t gfx; +static volatile int _g_posx, _g_posy; +static volatile g_btn_l, g_btn_r; +static volatile UINT32 g_color; + +// ------------------------------------------------------------- +void handler5(void) +{ + UINT32 volatile *pVGA_ctrl = (UINT32*)SYS_VGA_CTRL; + + // Ack + *pVGA_ctrl |= SYS_VGA_BIT_BUFCHG_FLAG; + +} + +void handler6(void) +{ + int p, i; + ps2_if_t *pIF; + UINT8 mouse_rsp[3]; + UINT32 timeout_count, key; + + INT32 dx, dy; + + for (p=0; p < PS2_get_num_if(); p++) + { + pIF = PS2_get_if(p); + if (SYS_PS2_BIT_RX_ERR_FLAG & *pIF->pCTRL) + fprintf(stderr, "PS2[%d]: Status = 0x%08X\n", p, *pIF->pCTRL); + + if (pIF->type == ps2_type_keyb) + { + while(SYS_PS2_BIT_RX_IRQ & *pIF->pCTRL) + { + key = *pIF->pDATA; + printf("Keyboard scan code = 0x%02X\n", key); + } + } + if (pIF->type == ps2_type_mouse) + { + if(!(SYS_PS2_BIT_RX_IRQ & *pIF->pCTRL)) + continue; + + for (i=0; i < 3; i++) + { + timeout_count = 100; + while(!(SYS_PS2_BIT_RX_IRQ & *pIF->pCTRL)) + { + timeout_count--; + if (!timeout_count) + { + break; + } + sleep(1); + } + if (!timeout_count) + { + break; + } + mouse_rsp[i] = (UINT8)*pIF->pDATA; + } + if (!timeout_count) + { + continue; + } + dx = mouse_rsp[1]; + if (mouse_rsp[0] & 0x10) + dx |= 0xFFFFFF00; + dy = mouse_rsp[2]; + if (mouse_rsp[0] & 0x20) + dy |= 0xFFFFFF00; + +// printf("dx = %5d, dy = %5d\n", dx, dy); + + mouse_x += dx; + mouse_y -= dy; + g_btn_l = 0; + if (mouse_rsp[0] & 0x01) + g_btn_l = 1; + + if (mouse_rsp[0] & 0x02) + { + if (g_btn_r == 0) + { + g_color = (UINT32)rand(); + } + g_btn_r = 1; + } + else + g_btn_r = 0; + + + if (mouse_x < 0) + mouse_x = 0; + if (mouse_y < 0) + mouse_y = 0; + if (mouse_x > (gfx.w-1)) + mouse_x = gfx.w-1; + if (mouse_y >= (gfx.h-1)) + mouse_y = gfx.h-1; + +// Screen_csr_set_x(mouse_x); +// Screen_csr_set_y(mouse_y); + +// printf("x = %5d, y = %5d\n", mouse_x, mouse_y); + + } + } +} + +int main(void) +{ + + int i; + UINT32 volatile *pVGA_ctrl = (UINT32*)SYS_VGA_CTRL; + UINT32 volatile *pVGA_moffs_0 = (UINT32*)SYS_VGA_FB_FRONT; + UINT32 volatile *pVGA_moffs_1 = (UINT32*)SYS_VGA_FB_BACK; + UINT32 volatile *pVGA_cgcol = (UINT32*)SYS_VGA_CGCOL; + UINT32 volatile *pFlashPicture = (UINT32*)(SYS_FLASH_MEM + 0x00600000); + UINT32 framecount; + UINT32 start, end; + + interrupt_register(5, (void*)handler5); + interrupt_register(6, (void*)handler6); + + srand(clock()); + UART1_setbaud(460800); + + *pVGA_cgcol = 0x00FFFFFF; + _g_posx = _g_posy = 0; + g_color = 0xFFFFFFFF; + GFX_init(&gfx); + + GFX_set_background(&gfx, pFlashPicture, 800, 600, 1, 1); + box_create(&box, 256, 256); + GFX_box_draw(&gfx, &box, _g_posx, _g_posy, g_color); + GFX_show(&gfx); + printf("VGA status = %08X\n", *pVGA_ctrl); + + PS2_init(0); + PS2_init(1); + + // Flush buffer + PS2_flush(0); + PS2_flush(1); + +// interrupt_enable(5); + interrupt_enable(6); + + framecount = Screen_get_fps(); + start = clock(); + + while(1) + { + if (!framecount) + { + end = clock(); + framecount = Screen_get_fps(); + printf("%f FPS\n", (float)framecount/((float)(end-start)/CLOCKS_PER_SEC)); + start = clock(); + } + + GFX_frame(&gfx, GFX_FRAME_SYNC); + framecount--; + + while ((_g_posx != (UINT32)mouse_x) || (_g_posy != (UINT32)mouse_y) || g_btn_r || g_btn_l) + { + + GFX_restore(&gfx, &box, _g_posx, _g_posy); + + _g_posx = (UINT32)mouse_x; + _g_posy = (UINT32)mouse_y; + + if (g_btn_l && !g_btn_r) + { + GFX_box_draw_bg(&gfx, &box, _g_posx, _g_posy, g_color); + } + + if (g_btn_l && g_btn_r) + { + GFX_set_background(&gfx, pFlashPicture, 800, 600, 1, 1); + } + + GFX_box_draw(&gfx, &box, _g_posx, _g_posy, g_color); + break; + } + GFX_show(&gfx); + } + return 0; +} diff --git a/lib/CPUs/MIPS/bsp/examples/testbench.c b/lib/CPUs/MIPS/bsp/examples/testbench.c new file mode 100644 index 0000000..15d921d --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/testbench.c @@ -0,0 +1,1229 @@ +#include +#include +#include +#include +#include +#include +#include +#include "libsys.h" +#include "mips_gfx.h" + +#define TEST10_ERROR (ERROR | 0x1000) +#define TEST11_ERROR (ERROR | 0x1100) +#define TEST12_ERROR (ERROR | 0x1200) +#define TEST13_ERROR (ERROR | 0x1300) +#define TEST14_ERROR (ERROR | 0x1400) +#define TEST15_ERROR (ERROR | 0x1500) +#define TEST16_ERROR (ERROR | 0x1600) + +#define PIC_NX 800 +#define PIC_NY 600 + +extern int paranoia(int argc, char **argv); + +UINT32* pf(void) +{ + static UINT32 p; + + return &p; +} + +volatile UINT32 _g_blitter_rdy; +void ISR_blitter_rdy(void) +{ + UINT32 volatile *pVGA_ctrl = (UINT32*)SYS_VGA_CTRL; + + if (*pVGA_ctrl & SYS_VGA_BIT_BLIT_FIN) + { + putchar('.'); + // Ack + *pVGA_ctrl |= SYS_VGA_BIT_BLIT_ACK; + _g_blitter_rdy = 1; + } +} + +// ------------------------------------------------------------- +void LoadPic(UINT64 *pScreen, UINT32 screen_nx, UINT32 screen_ny, UINT32 *pImage, UINT32 image_nx, UINT32 image_ny, UINT32 image_scale_x, UINT32 image_scale_y) +{ + + UINT32 off_x, off_y; + UINT32 i, j, black; + UINT32 *pScr, *pImg; + + off_x = (screen_nx-(image_scale_x*image_nx))/2; + off_y = (screen_ny-(image_scale_y*image_ny))/2; + + black = 0; + pScr = (UINT32*)pScreen; + for (i=0; i < screen_nx*screen_ny; i += 8) + { + __gfx_block_set_8(pScr, 0); + pScr += 8; + } + + if (!pImage) + return; + + pScr = ((UINT32*)pScreen) + screen_nx*off_y + off_x; + pImg = pImage; + + for (i=0; i < image_ny*image_nx; i += 8) + { + __gfx_block_copy_8(pScr, pImg); + pScr += 8; + pImg += 8; + } + +/* + UINT32 off_x, off_y; + UINT32 i; + UINT32 *pScr; + + off_x = (screen_nx-(image_scale_x*image_nx))/2; + off_y = (screen_ny-(image_scale_y*image_ny))/2; + + memset(pScreen, 0, screen_nx*screen_ny*sizeof(UINT32)); + pScr = ((UINT32*)pScreen) + screen_nx*off_y + off_x; + + for (i=0; i < image_ny; i++) + { + memcpy(pScr, &pImage[i*image_nx], image_nx*sizeof(UINT32)); + pScr += screen_nx; + } +*/ +} + +int IsEndianBig(void) +{ + UINT8 *pBuf; + UINT32 word; + word = 0x12345678; + pBuf = (UINT8*)&word; + if (((*pBuf+0) == 0x12) && (*(pBuf+1) == 0x34) && (*(pBuf+2) == 0x56) && (*(pBuf+3) == 0x78)) + { + return 1; + } + if (((*pBuf+0) == 0x78) && (*(pBuf+1) == 0x56) && (*(pBuf+2) == 0x34) && (*(pBuf+3) == 0x12)) + { + return 0; + } + return -1; +} + +void handler3(void) +{ + volatile UINT32 *pUART_stat = (UINT32*)SYS_UART_STAT; + volatile UINT32 *pUART_data = (UINT32*)SYS_UART_DATA; + + if((0x10 & *pUART_stat)) + { + _putchar(0, (char)*pUART_data); + } + +} + +int g_cnt; +box_t box; +gfx_t gfx; +int posx, posy; + +void handler7(void) +{ + UINT32 volatile *pGPIO0 = (UINT32*)SYS_GPIO0; + UINT32 volatile *pTim_stat = (UINT32*)SYS_ITIM_STAT; + UINT32 volatile *pTim_ctrl = (UINT32*)SYS_ITIM_CTRL; + UINT32 volatile *pTim0_cmp = (UINT32*)SYS_ITIM0_CMP; + time_t curr_date; + struct tm *pDate; + + if (*pTim0_cmp < 0x200) + { + *pTim0_cmp = 0x200; + } + if (*pTim_stat & 1) + { + *pTim_stat = 1; + *pGPIO0 = g_cnt++; + GFX_frame(&gfx, GFX_FRAME_NOSYNC); + GFX_restore(&gfx, &box, posx, posy); + GFX_show(&gfx); + + posx = (UINT32)rand()%800; + posy = (UINT32)rand()%600; + GFX_frame(&gfx, GFX_FRAME_NOSYNC); + GFX_box_draw(&gfx, &box, posx, posy, (UINT32)rand()); + GFX_show(&gfx); + } + + if (*pTim_stat & 4) + { + *pTim_stat = 4; + curr_date = time(NULL); + pDate = gmtime(&curr_date); + fprintf(stderr, "%s", asctime(pDate)); + } + +} + +int fibonacci(int f0, int f1, int *pDst, int len) +{ + int i; + + i = 0; + + pDst[i++] = f0; + pDst[i++] = f1; + + for (; i < len; i++) + { + pDst[i] = pDst[i-2] + pDst[i-1]; + } + + return i; +} + +void PrintCPUinfo(void) +{ + int result, rev_id; + int cache_size, cache_line; + int eb; + + char *cpu_type_str[7] = {"invalid", "R2000", "R3000", "R6000", "R4000", "reserved", "R6000A"}; + + // Print Status register + result = CP0_SR_read(); + + printf("--------------------------------------------------\n"); + printf("Status : %8.8X\n", result); + + // Print Revision + result = CP0_PRID_read(); + rev_id = (result >> 8) & 0xFF; + printf("CPU type : MIPS "); + if ((rev_id > 0) && (rev_id < 0x07)) + { + printf(cpu_type_str[rev_id]); + printf(" Rev. "); + rev_id = result & 0xFF; + printf("%d", rev_id); + } + else + printf("Unknown"); + + eb = IsEndianBig(); + if (eb) + printf(" [Big-endian]\n"); + if (!eb) + printf(" [Little-endian]\n"); + if (eb < 0) + printf(" [Unknown endian]\n"); + + cache_size = (result >> 16) & 7; + cache_line = (result >> 19) & 7; + printf("I-Cache : %d kBytes (%d Bytes per line)\n", 4*(int)pow(2.0, (double)(8+cache_size))/1024, 4*(int)pow(2.0, (double)(cache_line))); + cache_size = (result >> 24) & 7; + cache_line = (result >> 27) & 7; + printf("D-Cache : %d kBytes (%d Bytes per line)\n", 4*(int)pow(2.0, (double)(8+cache_size))/1024, 4*(int)pow(2.0, (double)(cache_line))); + printf("--------------------------------------------------\n"); + +} + +UINT32 uncached_cachemiss_bug(void) +{ + UINT32 result; + UINT32 pMem[2]; + + pMem[0] = 0x12345678; + pMem[1] = 0xFFFFFFFF; + + __asm__ + ( + "cop0 34\n" + "lui $s0, 0xA000\n" + "lw $a0, 48($s0)\n" + "or $s1, $a0, $0\n" + "or $a2, $0, $0\n" + "addiu $a2, 0x7F00\n" + "sw $a2, 48($s0)\n" +// "lw $a1, 0(%[pMem])\n" + "lw $a0, 48($s0)\n" + "lw $a2, 4(%[pMem])\n" + "lw $a1, 0(%[pMem])\n" + "nop\n" + "sw $s1, 48($s0)\n" + "or %[val], $a0, $0\n" + : [val] "=r" (result) + : [pMem] "r" (pMem) + : "a0", "a1", "a2", "s0", "s1" + ); + return result; +} + +UINT32 non_aligned_load() +{ + UINT32 result; + UINT32 pMem[3]; + + __asm__ + ( + "li $t0, 0x01234567\n" + "li $t1, 0x89ABCDEF\n" + "sw $t0, 0(%[pMem])\n" + "sw $t1, 4(%[pMem])\n" + "li %[val], 0x55555555\n" + "lw %[val], 0(%[pMem])\n" + "lwl %[val], 5(%[pMem])\n" + : [val] "=r" (result) + : [pMem] "r" (pMem) + : "t0", "t1" + ); + + if (0 == IsEndianBig()) + { + if (0xCDEF4567 != result) + return ERROR; + } + else + { + if (0xABCDEF67 != result) + return ERROR; + } + return 0; + +} + +int Test10_LoadStore() +{ + int *buf, i, result, data, err; + volatile int *pPtr; + + buf = (int*)malloc(32*sizeof(int)); +// sputs("buf = "); +// print_word((int)buf); +// sputs("\n"); + + while(1) + { + err = TEST10_ERROR; + // Basic Load/Store + pPtr = buf; + *pPtr++ = 0x00000000; + *pPtr++ = 0x55555555; + *pPtr++ = 0xAAAAAAAA; + *pPtr++ = 0xFFFFFFFF; + pPtr = buf; + if (*pPtr++ != 0x00000000) + break; + if (*pPtr++ != 0x55555555) + break; + if (*pPtr++ != 0xAAAAAAAA) + break; + if (*pPtr++ != 0xFFFFFFFF) + break; + + // Filling from left + pPtr = buf; + data = 0x00000000; + for (i=0; i < 32; i++) + { + *pPtr++ = data; + data = data >> 1 | 0x80000000; + + } + pPtr = buf; + data = 0x00000000; + for (i=0; i < 32; i++) + { + + if (*pPtr++ != data) + break; + + data = data >> 1 | 0x80000000; + } + if (i != 32) + break; + + // Filling from right + pPtr = buf; + data = 0x00000000; + for (i=0; i < 32; i++) + { + *pPtr++ = data; + data = data << 1 | 1; + + } + pPtr = buf; + data = 0x00000000; + for (i=0; i < 32; i++) + { + + if (*pPtr++ != data) + break; + + data = data << 1 | 1; + } + if (i != 32) + break; + + // Walking ones + pPtr = buf; + data = 0x00000001; + for (i=0; i < 32; i++) + { + *pPtr++ = data; + data = data << 1; + + } + pPtr = buf; + data = 0x00000001; + for (i=0; i < 32; i++) + { + + if (*pPtr++ != data) + break; + + data = data << 1; + } + if (i != 32) + break; + + // Walking zeros + pPtr = buf; + data = 0xFFFFFFFE; + for (i=0; i < 32; i++) + { + *pPtr++ = data; + data = data << 1 | 1; + + } + pPtr = buf; + data = 0xFFFFFFFE; + for (i=0; i < 32; i++) + { + + if (*pPtr++ != data) + break; + + data = data << 1 | 1; + + } + if (i != 32) + break; + + err = NO_ERROR; + break; + } + free(buf); + + if (IS_ERROR(err)) + return err; + + if (IS_ERROR(non_aligned_load())) + return TEST10_ERROR | 1; + + if (IS_ERROR(uncached_cachemiss_bug())) + return TEST10_ERROR | 2; + + return NO_ERROR; + +} + + +#define NUM_ELEMENTS 10000 +#define NUM_RUNS 3 +int Test11_AddSub() +{ + int buf[NUM_ELEMENTS], result, i, j, diff, fill, num_right_elements, num_right_runs; + + fill = 0xAAAAAAAA; + + num_right_runs = 0; + + for (i=0; i < NUM_RUNS; i++) + { + for (j=0; j < NUM_ELEMENTS; j++) + { + buf[j] = fill; + fill = ((fill ^ j) - 1) << 1; + } + num_right_elements = 2; + result = fibonacci(i, i+1, buf, NUM_ELEMENTS); + for (j=2; j < NUM_ELEMENTS; j++) + { + diff = buf[j] - buf[j-1]; + if (diff == buf[j-2]) + num_right_elements++; + } + if (num_right_elements == NUM_ELEMENTS) + num_right_runs++; + + } + + if (num_right_runs != NUM_RUNS) + return TEST11_ERROR; + + return NO_ERROR; +} + +int Test12_MulDiv() +{ + int mix, i, j; + int s1, s2, sp, st; + div_t div_res; + long cl; + + cl = (long)clock(); + srand(cl); + for (i=0; i < 100; i++) + { + for (j=1; j < 100; j++) + { + mix = (int)rand(); + mix = (mix << 8) ^ (mix << 16); + s1 = (int)rand() ^ mix; + mix = (int)rand(); + mix = (mix << 8) ^ (mix << 16); + s2 = (int)rand() ^ mix; + if (!s2) + { + fprintf(stderr, "Test12_MulDiv(): Division by zero!\n"); + fprintf(stderr, "Clock() was 0x%8.8X\n", cl); + continue; + } + + div_res = div(s1, s2); + + sp = s2*div_res.quot; + st = div_res.rem + sp; + if (st != s1) + return TEST12_ERROR; + } + } + return NO_ERROR; +} + +int Test13_COP0_Load_Store(void) +{ + int i,size; + UINT32 *pSrc32, *pDst32; + + size = 0x2000; + pSrc32 = (UINT32*)0xBFC00000; + pDst32 = (UINT32*)calloc(size,sizeof(UINT32)); + for (i=0; i < size/4; i++) + { + CP0_TR_read_ptr(&pSrc32[i]); + CP0_TR_write_ptr(&pDst32[i]); + } + for (i=size/4-1; i >= 0; i--) + if (pDst32[i] != pSrc32[i]) + break; + + free(pDst32); + i++; + if (i) + return TEST13_ERROR; + + return NO_ERROR; +} + +int Test14_DCACHE_invalidate(void) +{ + int i,size; + UINT32 *pSrc32, *pDst32; + + size = 0x2000; + pSrc32 = (UINT32*)0xBFC00000; + pDst32 = (UINT32*)calloc(size,sizeof(UINT32)); + for (i=0; i < size/4; i++) + { + pDst32[i] = pSrc32[i]; + DCACHE_invalidate_at(&pDst32[i]); + } + for (i=size/4-1; i >= 0; i--) + { + DCACHE_invalidate_at(&pDst32[i]); + if (pDst32[i] != pSrc32[i]) + break; + } + + free(pDst32); + i++; + if (i) + return TEST14_ERROR; + + pDst32 = (UINT32*)calloc(size,sizeof(UINT32)); + for (i=0; i < size/4; i++) + { + pDst32[i] = pSrc32[i]; + } + DCACHE_invalidate_all(); + for (i=size/4-1; i >= 0; i--) + if (pDst32[i] != pSrc32[i]) + break; + + free(pDst32); + i++; + if (i) + return TEST14_ERROR; + + return NO_ERROR; +} + +#define PI_SCALE 10000 +#define PI_MAXARR 2800 +#define PI_ARRINIT 2000 + +int Test15_pi_calc() +{ + int i, j, k; + int carry = 0; + int arr[PI_MAXARR+1]; + UINT32 int_part, result; + UINT16 pi_res[200] = {0}; + UINT16 pi_ref[200] = + { + 3141,5926,5358,9793,2384,6264,3383,2795, 288,4197,1693,9937,5105,8209,7494,4592,3078,1640,6286,2089,9862,8034,8253,4211, + 7067,9821,4808,6513,2823, 664,7093,8446, 955, 582,2317,2535,9408,1284,8111,7450,2841, 270,1938,5211, 555,9644,6229,4895, + 4930,3819,6442,8810,9756,6593,3446,1284,7564,8233,7867,8316,5271,2019, 914,5648,5669,2346, 348,6104,5432,6648,2133,9360, + 7260,2491,4127,3724,5870, 660,6315,5881,7488,1520,9209,6282,9254, 917,1536,4367,8925,9036, 11,3305,3054,8820,4665,2138, + 4146,9519,4151,1609,4330,5727, 365,7595,9195,3092,1861,1738,1932,6117,9310,5118,5480,7446,2379,9627,4956,7351,8857,5272, + 4891,2279,3818,3011,9491,2983,3673,3624,4065,6643, 860,2139,4946,3952,2473,7190,7021,7986, 943,7027,7053,9217,1762,9317, + 6752,3846,7481,8467,6694, 513,2000,5681,2714,5263,5608,2778,5771,3427,5778,9609,1736,3717,8721,4684,4090,1224,9534,3014, + 6549,5853,7105, 792,2796,8925,8923,5420,1995,6112,1290,2196, 864, 344,1815,9813,6297,7477,1309,9605,1870,7211,3499,9999, + 8372,9780,4995,1059,7317,3281,6096,3185 + }; + + // setbuf(stdout, NULL); + k = 0; + for (i = 0; i <= PI_MAXARR; ++i) + arr[i] = PI_ARRINIT; + + for (i = PI_MAXARR; i; i -= 14) + { + int sum = 0; + for (j = i; j > 0; --j) + { + sum = sum*j + PI_SCALE*arr[j]; + arr[j] = sum % (j*2-1); + sum /= (j*2-1); + } + result = carry + sum/PI_SCALE; + int_part = PI_SCALE * (result / PI_SCALE); + pi_res[k] = (UINT16)(result - int_part); + carry = sum % PI_SCALE; + k++; + } + + for (k=0; k < sizeof(pi_ref)/sizeof(UINT16); k++) + { + printf("%d", pi_res[k]); + } + printf("\n"); + + if(memcmp(pi_res, pi_ref, sizeof(pi_ref))) + return TEST15_ERROR; + + return NO_ERROR; +} + +#define TEST_SIZE (16*1024*1024) // Bytes +#define SMALL_TEST_SIZE (8192) // Bytes +#define FLASH_SIZE (8*1024*1024) // Bytes + +int Test16_MemTest(void) +{ + int result, i, j, cnt, size; + UINT8 *ram8 = NULL; + UINT16 *ram16 = NULL; + UINT32 *ram32 = NULL; + UINT32 volatile *pFlashIO = (UINT32*)SYS_FLASH_IO; + UINT32 volatile *pFlashMem = (UINT32*)SYS_FLASH_MEM; + UINT32 volatile *pROM = (UINT32*)0xBFC00000; + UINT32 volatile *pVGA_src0 = (UINT32*)SYS_VGA_BLIT_SRC0; + UINT32 volatile *pVGA_dst = (UINT32*)SYS_VGA_BLIT_DST; + UINT32 volatile *pVGA_dimx_src0 = (UINT32*)SYS_VGA_BLIT_SRC0_DIMX; + UINT32 volatile *pVGA_dimx_dst = (UINT32*)SYS_VGA_BLIT_DST_DIMX; + UINT32 volatile *pVGA_nx = (UINT32*)SYS_VGA_BLIT_NX; + UINT32 volatile *pVGA_ny = (UINT32*)SYS_VGA_BLIT_NY; + UINT32 volatile *pVGA_ctrl = (UINT32*)SYS_VGA_CTRL; + UINT32 volatile *pVGA_moffs_0 = (UINT32*)SYS_VGA_FB_FRONT; + + + UINT32 *pSrc32, *pDst32; + UINT32 start, end; + + // ---------------------------------------------------------- + // Memtest BEGIN +/* printf("SSRAM Memory Test\r\n"); + printf("Small data test\r\n"); + printf("Write (32-Bit access)..."); + start = clock(); + for (j=0; j < TEST_SIZE/SMALL_TEST_SIZE; j++) + for (i=0; i < SMALL_TEST_SIZE/4; i++) + pSSRAM[i] = (UINT32)i; + + end = clock(); + printf("done (%.2f MByte/s)\n", (double)TEST_SIZE/(1000*(end-start))); + + PrintBuffer8((UINT8*)pSSRAM, 16, 256); + + printf("Verify (32-Bit access)..."); + start = clock(); + for (j=0; j < TEST_SIZE/SMALL_TEST_SIZE; j++) + for (i=SMALL_TEST_SIZE/4-1; i >= 0; i--) + if (pSSRAM[i] != (UINT32)i) + break; + + end = clock(); + i++; + if (i) + printf("failed\r\n"); + else + printf("passed (%.2f MByte/s)\n", (double)TEST_SIZE/(1000*(end-start))); +*/ + // ---------------------------------------------------------- + pSrc32 = (UINT32*)calloc(TEST_SIZE/4,sizeof(UINT32)); + pDst32 = (UINT32*)calloc(TEST_SIZE/4,sizeof(UINT32)); + + // Memtest BEGIN + printf("Dump first 16 bytes of flash blocks\n"); + for (i=0; i < FLASH_SIZE; i += 0x40000) + memdump((UINT8*)(pFlashIO+i/4), 0, 16, 16); + + printf("\n"); + + printf("SDRAM Memory Test\n"); + printf("Test size %d kByte\n\n", TEST_SIZE/1024); + + ram8 = (UINT8*)pDst32; + printf("Zeroize SDRAM (memset)..."); + start = clock(); + memset(ram8, 0, TEST_SIZE); + end = clock(); + printf("done (%.2f MByte/s)\n", (double)TEST_SIZE/(1024*1024*(double)(end-start)/CLOCKS_PER_SEC)); + + printf("Zeroize SDRAM (8-Bit access)..."); + start = clock(); + for (i=0; i < TEST_SIZE; i++) + ram8[i] = (UINT8)0; + + end = clock(); + printf("done (%.2f MByte/s)\n", (double)TEST_SIZE/(1024*1024*(double)(end-start)/CLOCKS_PER_SEC)); + + ram16 = (UINT16*)pDst32; + printf("Zeroize SDRAM (16-Bit access)..."); + start = clock(); + for (i=0; i < TEST_SIZE/2; i++) + ram16[i] = (UINT16)0; + + end = clock(); + printf("done (%.2f MByte/s)\n", (double)TEST_SIZE/(1024*1024*(double)(end-start)/CLOCKS_PER_SEC)); + + ram32 = (UINT32*)pDst32; + printf("Zeroize SDRAM (32-Bit access)..."); + start = clock(); + for (i=0; i < TEST_SIZE/4; i++) + ram32[i] = (UINT32)0; + + end = clock(); + printf("done (%.2f MByte/s)\n", (double)TEST_SIZE/(1024*1024*(double)(end-start)/CLOCKS_PER_SEC)); + + ram8 = (UINT8*)pDst32; + printf("Write SDRAM (8-Bit access)..."); + start = clock(); + for (i=0; i < TEST_SIZE; i++) + ram8[i] = (UINT8)i; + + end = clock(); + printf("done (%.2f MByte/s)\n", (double)TEST_SIZE/(1024*1024*(double)(end-start)/CLOCKS_PER_SEC)); + + printf("Verify SDRAM (8-Bit access)..."); + start = clock(); + for (i=TEST_SIZE-1; i >= 0; i--) + if (ram8[i] != (UINT8)i) + break; + + end = clock(); + i++; + if (i) + { + printf("failed\r\n"); + return TEST16_ERROR; + } + else + printf("passed (%.2f MByte/s)\n", (double)TEST_SIZE/(1024*1024*(double)(end-start)/CLOCKS_PER_SEC)); + + ram16 = (UINT16*)pDst32; + printf("Write SDRAM (16-Bit access)..."); + start = clock(); + for (i=0; i < TEST_SIZE/2; i++) + ram16[i] = (UINT16)i; + + end = clock(); + printf("done (%.2f MByte/s)\n", (double)TEST_SIZE/(1024*1024*(double)(end-start)/CLOCKS_PER_SEC)); + + printf("Verify SDRAM (16-Bit access)..."); + start = clock(); + for (i=TEST_SIZE/2-1; i >= 0; i--) + if (ram16[i] != (UINT16)i) + break; + + end = clock(); + i++; + if (i) + { + printf("failed\r\n"); + return TEST16_ERROR; + } + else + printf("passed (%.2f MByte/s)\n", (double)TEST_SIZE/(1024*1024*(double)(end-start)/CLOCKS_PER_SEC)); + + + ram32 = (UINT32*)pDst32; + printf("Write SDRAM (32-Bit access)..."); + start = clock(); + for (i=0; i < TEST_SIZE/4; i++) + { + ram32[i] = (UINT32)i; + } + + end = clock(); + printf("done (%.2f MByte/s)\n", (double)TEST_SIZE/(1024*1024*(double)(end-start)/CLOCKS_PER_SEC)); + + printf("Verify SDRAM (32-Bit access)..."); + start = clock(); + for (i=TEST_SIZE/4-1; i >= 0; i--) + { + if (ram32[i] != (UINT32)i) + break; + } + + end = clock(); + i++; + if (i) + { + printf("failed\r\n"); + return TEST16_ERROR; + } + else + printf("passed (%.2f MByte/s)\n", (double)TEST_SIZE/(1024*1024*(double)(end-start)/CLOCKS_PER_SEC)); + + printf("\n"); + printf("Small data test (size = %d kByte)\n", SMALL_TEST_SIZE/1024); + printf("Write SDRAM (32-Bit access)..."); + ram32 = (UINT32*)pDst32; + start = clock(); + for (j=0; j < TEST_SIZE/SMALL_TEST_SIZE; j++) + for (i=0; i < SMALL_TEST_SIZE/4; i++) + ram32[i] = (UINT32)i; + + end = clock(); + printf("done (%.2f MByte/s)\n", (double)TEST_SIZE/(1024*1024*(double)(end-start)/CLOCKS_PER_SEC)); + + // ------------------------------------------------------------------- + // Verify + printf("Verify SDRAM (32-Bit access)..."); + start = clock(); + for (j=0; j < TEST_SIZE/SMALL_TEST_SIZE; j++) + for (i=SMALL_TEST_SIZE/4-1; i >= 0; i--) + if (ram32[i] != (UINT32)i) + break; + + end = clock(); + i++; + if (i) + { + printf("failed\r\n"); + return TEST16_ERROR; + } + else + printf("passed (%.2f MByte/s)\n", (double)TEST_SIZE/(1024*1024*(double)(end-start)/CLOCKS_PER_SEC)); + + for (i=1024; i < 4*65536; i *= 2) + { + printf("Memcpy() (%d kByte)...", i/1024); + start = clock(); + for (j=0; j < TEST_SIZE/i; j++) + memcpy(pDst32, pSrc32, i); + + end = clock(); + printf("done (%.2f MByte/s)\n", (double)TEST_SIZE/(1024*1024*(double)(end-start)/CLOCKS_PER_SEC)); + } + for (i=1024; i < 4*65536; i *= 2) + { + printf("__gfx_copy_32() (%d kByte)...", i/1024); + start = clock(); + for (j=0; j < TEST_SIZE/i; j++) + __gfx_copy_32(pDst32, pSrc32, i/32); + + end = clock(); + printf("done (%.2f MByte/s)\n", (double)TEST_SIZE/(1024*1024*(double)(end-start)/CLOCKS_PER_SEC)); + } + // ------------------------------------------------------------------- + printf("\n"); + + printf("Memcpy() Flash(IO) => SDRAM \n"); + printf("Copying %d kBytes...", FLASH_SIZE/(1024)); + start = clock(); + memcpy(pDst32, (UINT32*)pFlashIO, FLASH_SIZE); + end = clock(); + printf("done (%.2f MByte/s)\n", (double)TEST_SIZE/(1024*1024*(double)(end-start)/CLOCKS_PER_SEC)); + printf("\n"); + + printf("Memcpy() Flash(MEM) => SDRAM \n"); + printf("Copying %d kBytes...", FLASH_SIZE/(1024)); + start = clock(); + memcpy(pDst32, (UINT32*)pFlashMem, FLASH_SIZE); + end = clock(); + printf("done (%.2f MByte/s)\n", (double)TEST_SIZE/(1024*1024*(double)(end-start)/CLOCKS_PER_SEC)); + printf("\n"); + + interrupt_register(5, (void*)ISR_blitter_rdy); + interrupt_enable(5); + *pVGA_ctrl |= SYS_VGA_BIT_BLIT_FIN_INTEN; + printf("Blitter speed test (scan disabled)..."); + *pVGA_src0 = (UINT32)pSrc32; + *pVGA_dst = (UINT32)pDst32; + *pVGA_dimx_src0 = (UINT32)0; + *pVGA_dimx_dst = (UINT32)0; + *pVGA_nx = (UINT32)TEST_SIZE/4 - 1; + *pVGA_ny = (UINT32)0; + + start = clock(); + for (i=0; i < 10; i++) + { + _g_blitter_rdy = 0; + *pVGA_ctrl |= SYS_VGA_BIT_BLIT_REQ; + while (!_g_blitter_rdy); + } + end = clock(); + printf("done (%.2f MByte/s)\n", (double)(10*TEST_SIZE)/(1024*1024*(double)(end-start)/CLOCKS_PER_SEC)); + printf("\n"); + + printf("Blitter speed test (scan enabled)..."); + *pVGA_ctrl |= SYS_VGA_BIT_MSTEN; + sleep(500); + *pVGA_src0 = (UINT32)pSrc32; + *pVGA_dst = (UINT32)pDst32; + *pVGA_dimx_src0 = (UINT32)0; + *pVGA_dimx_dst = (UINT32)0; + *pVGA_nx = (UINT32)TEST_SIZE/4 - 1; + *pVGA_ny = (UINT32)0; + + start = clock(); + for (i=0; i < 10; i++) + { + _g_blitter_rdy = 0; + *pVGA_ctrl |= SYS_VGA_BIT_BLIT_REQ; + while (!_g_blitter_rdy); + } + end = clock(); + printf("done (%.2f MByte/s)\n", (double)(10*TEST_SIZE)/(1024*1024*(double)(end-start)/CLOCKS_PER_SEC)); + printf("\n"); + *pVGA_ctrl &= ~SYS_VGA_BIT_MSTEN; + *pVGA_ctrl &= ~SYS_VGA_BIT_BLIT_FIN_INTEN; + interrupt_disable(5); + + size = 0x2000; + memcpy(pDst32, (UINT32*)pROM, size); + printf("Verify boot ROM..."); + for (i=size/4-1; i >= 0; i--) + if (pDst32[i] != pROM[i]) + break; + i++; + if (i) + { + printf("failed\r\n"); + return TEST16_ERROR; + } + else + printf("passed\r\n"); + + printf("Verify FLASH(IO) <=> FLASH(MEM)..."); + if (!memcmp((UINT32*)pFlashIO, (UINT32*)pFlashMem, FLASH_SIZE)) + printf("passed\r\n"); + else + { + printf("failed\r\n"); + return TEST16_ERROR; + } + +// memdump((UINT8*)pSrc32, 0, 16, size); +// memdump((UINT8*)0x40000000, 0, 16, 1024); + + // Memtest END + // ---------------------------------------------------------- + free(pSrc32); + free(pDst32); + + sputs("\r\n"); + return 0; +} + +int main (void) +{ + int result, i, j, cnt, size; + UINT32 volatile *pUART_baud = (UINT32*)SYS_UART_BAUD; + UINT32 volatile *pUART_stat = (UINT32*)SYS_UART_STAT; + UINT32 volatile *pReg = (UINT32*)SYS_LED_PORT; + UINT32 volatile *pReg_usec = (UINT32*)SYS_TIMER_USEC; + UINT32 volatile *pReg_sec = (UINT32*)SYS_TIMER_SEC; + UINT32 volatile *pSSRAM = (UINT32*)SYS_SSRAM_IO; + UINT32 volatile *pTim_ctrl = (UINT32*)SYS_ITIM_CTRL; + UINT32 volatile *pTim_stat = (UINT32*)SYS_ITIM_STAT; + UINT32 volatile *pTim0_cnt = (UINT32*)SYS_ITIM0_CNT; + UINT32 volatile *pTim0_cmp = (UINT32*)SYS_ITIM0_CMP; + UINT32 volatile *pTim1_cnt = (UINT32*)SYS_ITIM1_CNT; + UINT32 volatile *pTim1_cmp = (UINT32*)SYS_ITIM1_CMP; + UINT32 volatile *pVGA_cgcol = (UINT32*)SYS_VGA_CGCOL; + UINT32 volatile *pFlashPicture = (UINT32*)(SYS_FLASH_MEM + 0x00600000); + + UINT32 volatile *pVGA_src0 = (UINT32*)SYS_VGA_BLIT_SRC0; + UINT32 volatile *pVGA_dst = (UINT32*)SYS_VGA_BLIT_DST; + UINT32 volatile *pVGA_dimx_src0 = (UINT32*)SYS_VGA_BLIT_SRC0_DIMX; + UINT32 volatile *pVGA_dimx_dst = (UINT32*)SYS_VGA_BLIT_DST_DIMX; + UINT32 volatile *pVGA_nx = (UINT32*)SYS_VGA_BLIT_NX; + UINT32 volatile *pVGA_ny = (UINT32*)SYS_VGA_BLIT_NY; + UINT32 volatile *pVGA_ctrl = (UINT32*)SYS_VGA_CTRL; + UINT32 volatile *pVGA_moffs_0 = (UINT32*)SYS_VGA_FB_FRONT; + + UINT32 screen_res_x, screen_res_y, screen_fps; + UINT64 *pBuf64_0, *pBuf64_1; + time_t curr_date; + struct tm *pDate, date; + UINT32 start, end; + char sel[80]; + struct timeval time_sec; + + + g_cnt = 1; + Screen_clr(); + + *pVGA_cgcol = 0x00FFFFFF; + + *pTim0_cnt = 0; + *pTim1_cnt = 0; + *pTim0_cmp = 0x4000; + *pTim1_cmp = 100000000; + *pTim_stat = (1 << 2) | (1 << 0); + *pTim_ctrl = (3 << 2); + +// *pUART_baud = 1; + + setbuf(stdout, NULL); + PrintCPUinfo(); + + interrupt_register(3, handler3); + fprintf(stderr, "UART interrupt registered.\n"); + + interrupt_register(7, handler7); + fprintf(stderr, "Timer interrupt registered.\n"); + + calibrate_delay(); + + printf("\n"); + + printf("Aktuelles Datum\n"); + curr_date = time(NULL); + pDate = gmtime(&curr_date); + puts(asctime(pDate)); + + if (curr_date < 2) + { + printf("Datum und Uhrzeit setzen? [j/N]: "); + scanf("%s", sel); + if (toupper(sel[0]) == 'J') + { + do + { + printf("Datum\n"); + printf("Jahr : "); + scanf("%d", &date.tm_year); + printf("Monat : "); + scanf("%d", &date.tm_mon); + printf("Tag : "); + scanf("%d", &date.tm_mday); + + printf("Uhrzeit\n"); + printf("Stunde : "); + scanf("%d", &date.tm_hour); + printf("Minute : "); + scanf("%d", &date.tm_min); + printf("Sekunde : "); + scanf("%d", &date.tm_sec); + + date.tm_year -= 1900; + date.tm_mon -= 1; + time_sec.tv_sec = mktime(&date); + time_sec.tv_usec = 0; + settimeofday(&time_sec, NULL); + + printf("Datum\n"); + curr_date = time(NULL); + pDate = gmtime(&curr_date); + puts(asctime(pDate)); + printf("\nOK? [J/n]: "); + scanf("%s", sel); + printf("sel=%d\n", (int)sel[0]); + + + } while(toupper(sel[0]) == 'N'); + } + } + srand(clock()); + *pReg = uncached_cachemiss_bug(); + Test16_MemTest(); + + printf("pf = %08X\n", (UINT32)pf()); + *pf() = 0x1234; + printf("*pf = %08X\n", (UINT32)*pf()); + + box_create(&box, 32, 32); + GFX_init(&gfx); + + start = clock(); + for (i=0; i < 100000; i++) + { + GFX_box_draw_direct(&gfx, &box, (UINT32)rand()%800, (UINT32)rand()%600, (UINT32)rand()); + } + + end = clock(); + printf("Fillrate %f rect/s\n", (float)i/((float)(end-start)/CLOCKS_PER_SEC)); + sleep(2000); + + GFX_frame(&gfx, GFX_FRAME_SYNC); + GFX_set_background(&gfx, pFlashPicture, 800, 600, 1, 1); + posx = posy = 0; + GFX_show(&gfx); + +// while(1) + { + // Blitter test + fprintf(stderr, "Blit start\n"); + *pVGA_src0 = (UINT32)*pFlashPicture; + *pVGA_dst = (UINT32)*pVGA_moffs_0; + *pVGA_dimx_src0 = (UINT32)4*800; + *pVGA_dimx_dst = (UINT32)4*800; + *pVGA_nx = (UINT32)800 - 1; + *pVGA_ny = (UINT32)600 - 1; + *pVGA_ctrl |= SYS_VGA_BIT_BLIT_REQ; + while (*pVGA_ctrl & SYS_VGA_BIT_BLIT_BSY); + + fprintf(stderr, "Blit end\n"); + sleep(250); + + // Blitter test + fprintf(stderr, "Blit start\n"); + *pVGA_src0 = (UINT32)gfx.pBG; + *pVGA_dst = (UINT32)*pVGA_moffs_0; + *pVGA_dimx_src0 = (UINT32)4*800; + *pVGA_dimx_dst = (UINT32)4*800; + *pVGA_nx = (UINT32)800 - 1; + *pVGA_ny = (UINT32)600 - 1; + *pVGA_ctrl |= SYS_VGA_BIT_BLIT_REQ; + while (*pVGA_ctrl & SYS_VGA_BIT_BLIT_BSY); + + fprintf(stderr, "Blit end\n"); + sleep(1000); + } + + + interrupt_enable(7); + interrupt_enable(3); + *pTim_ctrl |= 3; + *pUART_stat |= (1 << 6); + + cnt = 0; + while (1) + { + for (i=0; i < 100000; i++) + { + interrupt_disable(7); + } + for (i=0; i < 100000; i++) + { + interrupt_enable(7); + } + + *pReg = cnt & 0x3FFFFFFF; + + printf("-------------------------------------------\n"); + printf("-- LoadStore ------------------------------\n"); + printf("-------------------------------------------\n"); + result = Test10_LoadStore(); + if (IS_ERROR(result)) + break; + printf("passed\n\n"); + + printf("-------------------------------------------\n"); + printf("-- AddSub ---------------------------------\n"); + printf("-------------------------------------------\n"); + result = Test11_AddSub(); + if (IS_ERROR(result)) + break; + printf("passed\n\n"); + + printf("-------------------------------------------\n"); + printf("-- MulDiv ---------------------------------\n"); + printf("-------------------------------------------\n"); + result = Test12_MulDiv(); + if (IS_ERROR(result)) + break; + printf("passed\n\n"); + + printf("-------------------------------------------\n"); + printf("-- Cop0 LWZ0 and SWC0 ---------------------\n"); + printf("-------------------------------------------\n"); + result = Test13_COP0_Load_Store(); + if (IS_ERROR(result)) + break; + printf("passed\n\n"); + + printf("-------------------------------------------\n"); + printf("-- D-Cache invalidate ---------------------\n"); + printf("-------------------------------------------\n"); + result = Test14_DCACHE_invalidate(); + if (IS_ERROR(result)) + break; + printf("passed\n\n"); + + printf("-------------------------------------------\n"); + printf("-- PI calc --------------------------------\n"); + printf("-------------------------------------------\n"); + result = Test15_pi_calc(); + if (IS_ERROR(result)) + break; + printf("passed\n\n"); + + printf("-------------------------------------------\n"); + printf("-- Paranoia -------------------------------\n"); + printf("-------------------------------------------\n"); + paranoia(1, NULL); + printf("passed\n\n"); + +// printf("-------------------------------------------\n"); +// printf("-- Mem Test -------------------------------\n"); +// printf("-------------------------------------------\n"); +// result = Test16_MemTest(); +// if (IS_ERROR(result)) +// break; +// printf("passed\n\n"); + + printf("Iteration %d: Passed\n", cnt); + curr_date = time(NULL); + pDate = gmtime(&curr_date); + puts(asctime(pDate)); + cnt++; + *pTim0_cmp = 0x4000 + (UINT32)(rand() & 0x00FFFFFF); + *pTim_ctrl |= 1; + +// printf("V=%.17e\n", pow((double)cnt-1, (double)cnt)); + } + *pReg = 0x40000000 | cnt; + fprintf(stderr, "Failed with error %8.8X\n", result); + + return 1; + +} + diff --git a/lib/CPUs/MIPS/bsp/examples/testlibusb.c b/lib/CPUs/MIPS/bsp/examples/testlibusb.c new file mode 100644 index 0000000..5b48601 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/testlibusb.c @@ -0,0 +1,210 @@ +/* testlibusb.c */ + +#include +#include +#include +#include +#include +#include +#include "tiffio.h" + + +#define BUFLEN (256*1024) +#define FLASHSIZE (2*1024*1024) +int main(int argc, char *argv[]) +{ + char *pBuf; + int ret, i, xfer_cnt, filesize, size; + char string[256]; + double start, end; + struct timeval t; + FILE *pFile; + TIFF *pTif; + ttag_t config, photometric; + uint16 nSamples, nBits; + uint32 width, height; + uint32* raster; + + typedef struct _scmd_t + { + unsigned sync; + unsigned code; + unsigned len; + } cmd_t; + + cmd_t cmd_read = {0xC24755AA, 2, BUFLEN}; + cmd_t cmd_write = {0xC24755AA, 1, BUFLEN}; + cmd_t cmd_flash_read = {0xC24755AA, 3, FLASHSIZE}; + cmd_t cmd_flash_write = {0xC24755AA, 4, FLASHSIZE}; + + libusb_context *pCtx; + libusb_device_handle *handle; + size_t cnt; + + ret = libusb_init(&pCtx); + if (ret != LIBUSB_SUCCESS) + { + printf("Error %08X\n", ret); + return 1; + } + + libusb_set_debug(pCtx, 3); + + handle = libusb_open_device_with_vid_pid (pCtx, 0x04B4, 0x7200); + if (!handle) + { + printf("Error on opening device\n"); + return 1; + } + + pBuf = (char*)malloc(BUFLEN); + memset(pBuf, 0, BUFLEN); + + // ------------------------------------------------------ + printf("Send command\n"); + // ------------------------------------------------------ + ret = libusb_bulk_transfer (handle, 0x01, (char*)&cmd_write, sizeof(cmd_t), &xfer_cnt, 5000); + if (ret != LIBUSB_SUCCESS) + { + printf("Error %08X\n", ret); + return 1; + } + gettimeofday(&t, NULL); + start = t.tv_sec + 1E-6*t.tv_usec; + ret = libusb_bulk_transfer(handle, 0x01, (char*)pBuf, cmd_write.len, &xfer_cnt, 5000); + size = xfer_cnt; + gettimeofday(&t, NULL); + end = t.tv_sec + 1E-6*t.tv_usec; + if (ret != LIBUSB_SUCCESS) + { + printf("Error %08X\n", ret); + return 1; + } + printf("Sent %d bytes\n", size); + printf("Data rate: %.2f kbyte/s\n", (double)size/(1024*(end-start))); + + // ------------------------------------------------------ + printf("Read command\n"); + // ------------------------------------------------------ + ret = libusb_bulk_transfer(handle, 0x01, (char*)&cmd_read, sizeof(cmd_t), &xfer_cnt, 5000); + if (ret != LIBUSB_SUCCESS) + { + printf("Error %08X\n", ret); + return 1; + } + gettimeofday(&t, NULL); + start = t.tv_sec + 1E-6*t.tv_usec; + ret = libusb_bulk_transfer(handle, 0x82, (char*)pBuf, cmd_read.len, &xfer_cnt, 5000); + size = xfer_cnt; + gettimeofday(&t, NULL); + end = t.tv_sec + 1E-6*t.tv_usec; + if (ret != LIBUSB_SUCCESS) + { + printf("Error %08X\n", ret); + return 1; + } + printf("Received %d bytes\n", size); + printf("Data rate: %.2f kbyte/s\n", (double)size/(1024*(end-start))); + free(pBuf); + + // ------------------------------------------------------ + printf("Read Flash\n"); + // ------------------------------------------------------ + pBuf = (char*)malloc(FLASHSIZE); + memset(pBuf, 0, FLASHSIZE); + ret = libusb_bulk_transfer(handle, 0x01, (char*)&cmd_flash_read, sizeof(cmd_t), &xfer_cnt, 5000); + if (ret != LIBUSB_SUCCESS) + { + printf("Error %08X\n", ret); + return 1; + } + + gettimeofday(&t, NULL); + start = t.tv_sec + 1E-6*t.tv_usec; + ret = libusb_bulk_transfer(handle, 0x82, (char*)pBuf, cmd_flash_read.len, &xfer_cnt, 500000); + size = xfer_cnt; + gettimeofday(&t, NULL); + end = t.tv_sec + 1E-6*t.tv_usec; + if (ret != LIBUSB_SUCCESS) + { + printf("Error %08X\n", ret); + return 1; + } + printf("Received %d bytes\n", size); + printf("Data rate: %.2f kbyte/s\n", (double)size/(1024*(end-start))); + + pFile = fopen("./flash.bin", "wb"); + fwrite(pBuf, 1, size, pFile); + fclose(pFile); + free(pBuf); + + if (argc > 1) + { + // ------------------------------------------------------ + printf("Write Flash (File = %s)\n", argv[1]); + // ------------------------------------------------------ + pTif = TIFFOpen(argv[1],"r"); + if (!pTif) + { + printf("Unable to open TIFF-file!\n"); + return 1; + } + ret = TIFFGetField(pTif, TIFFTAG_IMAGEWIDTH, &width); + ret = TIFFGetField(pTif, TIFFTAG_IMAGELENGTH, &height); + + printf("TIFFTAG_IMAGEWIDTH = %d\n", width); + printf("TIFFTAG_IMAGELENGTH = %d\n", height); + + filesize = width * height * sizeof (uint32); + + raster = (uint32*) _TIFFmalloc(filesize); + if (raster != NULL) + { + ret = TIFFReadRGBAImageOriented(pTif, width, height, raster, ORIENTATION_TOPLEFT, 0); + if (!ret) + { + printf("Unable to reading TIFF-file!\n"); + return 1; + } + } + TIFFClose(pTif); + + printf ("File size = %d\n", filesize); + if (filesize > FLASHSIZE) + { + printf("Cannot write flash: image to large!\n"); + return 1; + } + + cmd_flash_write.len = filesize; + ret = libusb_bulk_transfer(handle, 0x01, (char*)&cmd_flash_write, sizeof(cmd_t), &xfer_cnt, 5000); + if (ret != LIBUSB_SUCCESS) + { + printf("Error %08X\n", ret); + return 1; + } + + gettimeofday(&t, NULL); + start = t.tv_sec + 1E-6*t.tv_usec; + size = 0; + ret = libusb_bulk_transfer(handle, 0x01, (char*)raster, filesize, &xfer_cnt, 500000); + if (ret != LIBUSB_SUCCESS) + { + printf("Error %08X\n", ret); + return 1; + } + size += xfer_cnt; + gettimeofday(&t, NULL); + end = t.tv_sec + 1E-6*t.tv_usec; + printf("Sent %d bytes\n", size); + printf("Data rate: %.2f kbyte/s\n", (double)size/(1024*(end-start))); + + _TIFFfree(raster); + + } + + libusb_close(handle); + libusb_exit(pCtx); + return 0; + +} diff --git a/lib/CPUs/MIPS/bsp/examples/ucb.c b/lib/CPUs/MIPS/bsp/examples/ucb.c new file mode 100644 index 0000000..d3b9a82 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/ucb.c @@ -0,0 +1,44 @@ +#include "libsys.h" + +int uncached_cachemiss_bug(UINT32* pMem) +{ + UINT32 result; + + pMem[0] = 0x12345678; + pMem[1] = 0xFFFFFFFF; + + DCACHE_invalidate_all(); + + __asm__ + ( + "lui $s0, 0xA000\n" + "lw $a0, 32($s0)\n" + "or $s1, $a0, $0\n" + "or $a2, $0, $0\n" + "addiu $a2, 1\n" + "sw $a2, 32($s0)\n" +// "lw $a1, 0(%[pMem])\n" + "lw $a0, 32($s0)\n" + "lw $a2, 4(%[pMem])\n" + "lw $a1, 0(%[pMem])\n" + "nop\n" + "sw $s1, 8($s0)\n" + "or %[val], $a0, $0\n" + : [val] "=r" (result) + : [pMem] "r" (pMem) + : "a0", "a1", "a2", "s0", "s1" + ); + return result; +} + +int main() +{ + UINT32 volatile *pLed = (UINT32*)SYS_LED_PORT; + int buf[256], res; + + res = uncached_cachemiss_bug(buf); + *pLed = res; + + return res; + +} diff --git a/lib/CPUs/MIPS/bsp/examples/whet.c b/lib/CPUs/MIPS/bsp/examples/whet.c new file mode 100644 index 0000000..d939910 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/whet.c @@ -0,0 +1,265 @@ +/* + * @(#)whet.c 1.1 + */ + +/* + * Whetstone benchmark in C. This program is a translation of the + * original Algol version in "A Synthetic Benchmark" by H.J. Curnow + * and B.A. Wichman in Computer Journal, Vol 19 #1, February 1976. + * + * Used to test compiler optimization and floating point performance. + */ + +/* + * Compile with -DMEASURE_TIME for time measurement. + * + * Compile with -DPOUT to print intermediate results. + * Running this benchmark without printing the intermediate results is + * contrary to the authors' intentions! But using serial I/O can draw back + * the performance extremely when low baud rate communication is used. + */ +#define MEASURE_TIME 1 +//#define POUT 1 + +#define ITERATIONS 10 /* 10 Million Whetstone instructions */ + +#include +#include + +#ifdef MEASURE_TIME +#include +unsigned long Begin_Time,End_Time,Total_Time; +double whetstones; +#endif + +#define Pout(n, j, k, x1, x2, x3, x4) pout(n, j, k, x1, x2, x3, x4); + +double xx1, xx2, xx3, xx4, x, y, z, t, t1, t2; +double e1[4]; +unsigned int i, j, k, l, n1, n2, n3, n4, n6, n7, n8, n9, n10, n11; + +main() +{ + printf("\nWhetstone Benchmark\n\n"); + + printf( "%d iterations\n", ITERATIONS ); + +#ifdef MEASURE_TIME + Begin_Time = clock(); +#endif + + /* initialize constants */ + + t = 0.499975; + t1 = 0.50025; + t2 = 2.0; + + /* set values of module weights */ + + n1 = 0 * ITERATIONS; + n2 = 12 * ITERATIONS; + n3 = 14 * ITERATIONS; + n4 = 345 * ITERATIONS; + n6 = 210 * ITERATIONS; + n7 = 32 * ITERATIONS; + n8 = 899 * ITERATIONS; + n9 = 616 * ITERATIONS; + n10 = 0 * ITERATIONS; + n11 = 93 * ITERATIONS; + +/* MODULE 1: simple identifiers */ + + xx1 = 1.0; + xx2 = xx3 = xx4 = -1.0; + + for(i = 1; i <= n1; i += 1) { + xx1 = ( xx1 + xx2 + xx3 - xx4 ) * t; + xx2 = ( xx1 + xx2 - xx3 + xx4 ) * t; + xx3 = ( xx1 - xx2 + xx3 + xx4 ) * t; + xx4 = (-xx1 + xx2 + xx3 + xx4 ) * t; + } +#ifdef POUT + Pout(n1, n1, n1, xx1, xx2, xx3, xx4); +#endif + + +/* MODULE 2: array elements */ + + e1[0] = 1.0; + e1[1] = e1[2] = e1[3] = -1.0; + + for (i = 1; i <= n2; i +=1) { + e1[0] = ( e1[0] + e1[1] + e1[2] - e1[3] ) * t; + e1[1] = ( e1[0] + e1[1] - e1[2] + e1[3] ) * t; + e1[2] = ( e1[0] - e1[1] + e1[2] + e1[3] ) * t; + e1[3] = (-e1[0] + e1[1] + e1[2] + e1[3] ) * t; + } +#ifdef POUT + Pout(n2, n3, n2, e1[0], e1[1], e1[2], e1[3]); +#endif + +/* MODULE 3: array as parameter */ + + for (i = 1; i <= n3; i += 1) + pa(e1); +#ifdef POUT + Pout(n3, n2, n2, e1[0], e1[1], e1[2], e1[3]); +#endif + +/* MODULE 4: conditional jumps */ + + j = 1; + for (i = 1; i <= n4; i += 1) { + if (j == 1) + j = 2; + else + j = 3; + + if (j > 2) + j = 0; + else + j = 1; + + if (j < 1 ) + j = 1; + else + j = 0; + } +#ifdef POUT + Pout(n4, j, j, xx1, xx2, xx3, xx4); +#endif + +/* MODULE 5: omitted */ + +/* MODULE 6: integer arithmetic */ + + j = 1; + k = 2; + l = 3; + + for (i = 1; i <= n6; i += 1) { + j = j * (k - j) * (l -k); + k = l * k - (l - j) * k; + l = (l - k) * (k + j); + + e1[l - 2] = j + k + l; /* C arrays are zero based */ + e1[k - 2] = j * k * l; + } +#ifdef POUT + Pout(n6, j, k, e1[0], e1[1], e1[2], e1[3]); +#endif + +/* MODULE 7: trig. functions */ + + x = y = 0.5; + + for(i = 1; i <= n7; i +=1) { + x = t * atan(t2*sin(x)*cos(x)/(cos(x+y)+cos(x-y)-1.0)); + y = t * atan(t2*sin(y)*cos(y)/(cos(x+y)+cos(x-y)-1.0)); + } +#ifdef POUT + Pout(n7, j, k, x, x, y, y); +#endif + +/* MODULE 8: procedure calls */ + + x = y = z = 1.0; + + for (i = 1; i <= n8; i +=1) + p3(x, y, &z); +#ifdef POUT + Pout(n8, j, k, x, y, z, z); +#endif + +/* MODULE9: array references */ + + j = 1; + k = 2; + l = 3; + + e1[0] = 1.0; + e1[1] = 2.0; + e1[2] = 3.0; + + for(i = 1; i <= n9; i += 1) + p0(); +#ifdef POUT + Pout(n9, j, k, e1[0], e1[1], e1[2], e1[3]); +#endif + +/* MODULE10: integer arithmetic */ + + j = 2; + k = 3; + + for(i = 1; i <= n10; i +=1) { + j = j + k; + k = j + k; + j = k - j; + k = k - j - j; + } +#ifdef POUT + Pout(n10, j, k, xx1, xx2, xx3, xx4); +#endif + +/* MODULE11: standard functions */ + + x = 0.75; + for(i = 1; i <= n11; i +=1) + x = sqrt( exp( log(x) / t1)); + +#ifdef POUT + Pout(n11, j, k, x, x, x, x); +#endif + +#ifdef MEASURE_TIME + End_Time = clock(); + + Total_Time = End_Time - Begin_Time; /* in 1/ seconds */ + + whetstones = (1e5 * ITERATIONS * CLOCKS_PER_SEC) / Total_Time; + printf("\nWhetstone runs in %ld clock ticks (%d). %ld Kwhets/second\n", + Total_Time, CLOCKS_PER_SEC, (long) whetstones / 1000 ); +#endif +} + +pa(e) +double e[4]; +{ + register int j; + + j = 0; + lab: + e[0] = ( e[0] + e[1] + e[2] - e[3] ) * t; + e[1] = ( e[0] + e[1] - e[2] + e[3] ) * t; + e[2] = ( e[0] - e[1] + e[2] + e[3] ) * t; + e[3] = ( -e[0] + e[1] + e[2] + e[3] ) / t2; + j += 1; + if (j < 6) + goto lab; +} + +p3(x, y, z) +double x, y, *z; +{ + x = t * (x + y); + y = t * (x + y); + *z = (x + y) /t2; +} + +p0() +{ + e1[j] = e1[k]; + e1[k] = e1[l]; + e1[l] = e1[j]; +} + +#ifdef POUT +pout(n, j, k, x1, x2, x3, x4) +unsigned int n, j, k; +double x1, x2, x3, x4; +{ + printf("%5u %5u %5u %11.3e %11.3e %11.3e %11.3e\n", + n, j, k, x1, x2, x3, x4); +} +#endif