aboutsummaryrefslogtreecommitdiffstats
path: root/avr-test
diff options
context:
space:
mode:
Diffstat (limited to 'avr-test')
-rw-r--r--avr-test/Makefile168
-rwxr-xr-xavr-test/avr-fusedump.bash102
-rwxr-xr-xavr-test/ledcube.binbin0 -> 4402 bytes
-rwxr-xr-xavr-test/ledcube.elfbin0 -> 32968 bytes
-rw-r--r--avr-test/ledcube.hex277
-rw-r--r--avr-test/ledcube.lst3367
-rw-r--r--avr-test/ledcube.map783
-rwxr-xr-xavr-test/ledcube.srec278
-rwxr-xr-xavr-test/ledcube_eeprom.bin0
-rw-r--r--avr-test/ledcube_eeprom.hex1
-rwxr-xr-xavr-test/ledcube_eeprom.srec2
l---------avr-test/mc1
-rw-r--r--avr-test/src/cube.h32
-rw-r--r--avr-test/src/draw.cpp559
-rw-r--r--avr-test/src/draw.h71
-rw-r--r--avr-test/src/effect.cpp1021
-rw-r--r--avr-test/src/effect.h54
-rw-r--r--avr-test/src/fuses.txt6
-rw-r--r--avr-test/src/lisence.txt5
-rw-r--r--avr-test/src/main.c.old285
-rw-r--r--avr-test/src/main.cpp508
-rw-r--r--avr-test/src/main.h45
-rw-r--r--avr-test/tags150
23 files changed, 7715 insertions, 0 deletions
diff --git a/avr-test/Makefile b/avr-test/Makefile
new file mode 100644
index 0000000..4e97a43
--- /dev/null
+++ b/avr-test/Makefile
@@ -0,0 +1,168 @@
+PRG = ledcube
+OBJ = main.o draw.o effect.o
+#MCU_TARGET = at90s2313
+#MCU_TARGET = at90s2333
+#MCU_TARGET = at90s4414
+#MCU_TARGET = at90s4433
+#MCU_TARGET = at90s4434
+#MCU_TARGET = at90s8515
+#MCU_TARGET = at90s8535
+#MCU_TARGET = atmega128
+#MCU_TARGET = atmega1280
+#MCU_TARGET = atmega1281
+#MCU_TARGET = atmega1284p
+#MCU_TARGET = atmega16
+#MCU_TARGET = atmega163
+#MCU_TARGET = atmega164p
+#MCU_TARGET = atmega165
+#MCU_TARGET = atmega165p
+#MCU_TARGET = atmega168
+#MCU_TARGET = atmega169
+#MCU_TARGET = atmega169p
+#MCU_TARGET = atmega2560
+#MCU_TARGET = atmega2561
+#MCU_TARGET = atmega32
+#MCU_TARGET = atmega324p
+#MCU_TARGET = atmega325
+#MCU_TARGET = atmega3250
+#MCU_TARGET = atmega329
+#MCU_TARGET = atmega3290
+#MCU_TARGET = atmega48
+#MCU_TARGET = atmega64
+#MCU_TARGET = atmega640
+#MCU_TARGET = atmega644
+#MCU_TARGET = atmega644p
+#MCU_TARGET = atmega645
+#MCU_TARGET = atmega6450
+#MCU_TARGET = atmega649
+#MCU_TARGET = atmega6490
+MCU_TARGET = atmega8
+#MCU_TARGET = atmega8515
+#MCU_TARGET = atmega8535
+#MCU_TARGET = atmega88
+#MCU_TARGET = attiny2313
+#MCU_TARGET = attiny24
+#MCU_TARGET = attiny25
+#MCU_TARGET = attiny26
+#MCU_TARGET = attiny261
+#MCU_TARGET = attiny44
+#MCU_TARGET = attiny45
+#MCU_TARGET = attiny461
+#MCU_TARGET = attiny84
+#MCU_TARGET = attiny85
+#MCU_TARGET = attiny861
+
+#OPTIMIZE = -O2
+OPTIMIZE = -Os
+
+# One must use -ffunction-sections (compiler switch) AND -Wl,-gc-sections
+# (linker switch) to have the linker "garbage collect" (or remove) unused
+# sections. The -ffunction-sections switch places all functions within their
+# own section. You must use both together to make this work.
+DEFS = -ffunction-sections
+LIBS = -Wl,-gc-sections
+# You should not have to change anything below here.
+
+CC = avr-gcc
+CXX = avr-g++
+
+# Override is only needed by avr-lib build system.
+
+override CFLAGS = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS) #-fno-exceptions -fno-rtti
+override LDFLAGS = -Wl,-Map,$(PRG).map --relax
+
+OBJCOPY = avr-objcopy
+OBJDUMP = avr-objdump
+
+%.o: src/%.cpp
+ $(CXX) $(CFLAGS) -c -o $@ $^
+
+all: $(PRG).elf lst text eeprom
+ avr-size --mcu=$(MCU_TARGET) -C $(PRG).elf
+
+$(PRG).elf: $(OBJ)
+ $(CXX) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
+
+# dependency:
+#demo.o: demo.c iocompat.h
+#%.o: %.c
+
+clean:
+ rm -rf *.o $(PRG).elf *.eps *.png *.pdf *.bak
+ rm -rf *.lst *.map $(EXTRA_CLEAN_FILES)
+
+lst: $(PRG).lst
+
+%.lst: %.elf
+ $(OBJDUMP) -h -S $< > $@
+
+# Rules for building the .text rom images
+
+text: hex bin srec
+
+hex: $(PRG).hex
+bin: $(PRG).bin
+srec: $(PRG).srec
+
+%.hex: %.elf
+ $(OBJCOPY) -j .text -j .data -O ihex $< $@
+
+%.srec: %.elf
+ $(OBJCOPY) -j .text -j .data -O srec $< $@
+
+%.bin: %.elf
+ $(OBJCOPY) -j .text -j .data -O binary $< $@
+
+# Rules for building the .eeprom rom images
+
+eeprom: ehex ebin esrec
+
+ehex: $(PRG)_eeprom.hex
+ebin: $(PRG)_eeprom.bin
+esrec: $(PRG)_eeprom.srec
+
+%_eeprom.hex: %.elf
+ $(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@ \
+ || { echo empty $@ not generated; exit 0; }
+
+%_eeprom.srec: %.elf
+ $(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O srec $< $@ \
+ || { echo empty $@ not generated; exit 0; }
+
+%_eeprom.bin: %.elf
+ $(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O binary $< $@ \
+ || { echo empty $@ not generated; exit 0; }
+
+# Every thing below here is used by avr-libc's build system and can be ignored
+# by the casual user.
+
+FIG2DEV = fig2dev
+EXTRA_CLEAN_FILES = *.hex *.bin *.srec
+
+dox: eps png pdf
+
+eps: $(PRG).eps
+png: $(PRG).png
+pdf: $(PRG).pdf
+
+%.eps: %.fig
+ $(FIG2DEV) -L eps $< $@
+
+%.pdf: %.fig
+ $(FIG2DEV) -L pdf $< $@
+
+%.png: %.fig
+ $(FIG2DEV) -L png $< $@
+
+flash:
+ # for atmega8 :
+ avrdude -p m8 -c stk500v2 -P /dev/ttyUSB0 -e -U flash:w:$(PRG).hex
+ # for attiny25
+ #avrdude -p t25 -c stk500v2 -P /dev/ttyUSB0 -e -U flash:w:$(PRG).hex
+
+a: all flash
+
+size:
+ avr-size --mcu=$(MCU_TARGET) -t -A $(PRG).elf
+ avr-size --mcu=$(MCU_TARGET) -C $(PRG).elf
+ avr-nm --size-sort $(PRG).elf
diff --git a/avr-test/avr-fusedump.bash b/avr-test/avr-fusedump.bash
new file mode 100755
index 0000000..d6c6e50
--- /dev/null
+++ b/avr-test/avr-fusedump.bash
@@ -0,0 +1,102 @@
+#!/bin/bash
+#############################################################################
+#Bash script to dump the fuse bits for AVR microcontrollers and open
+#the Engbedded Atmel AVR Fuse Calculator with the current fuse settings.
+#
+#05-Nov-2009
+#Craig Heffner
+#http://www.hackingwithgum.com
+#############################################################################
+
+LFUSE=lfuse
+HFUSE=hfuse
+EFUSE=efuse
+URL="http://www.engbedded.com/cgi-bin/fcx.cgi?P=MMCU&V_LOW=$LFUSE&V_HIGH=$HFUSE&V_EXTENDED=$EFUSE&O_HEX=Apply+values"
+ADSUCCESS=OK
+ADOK=0
+FUSE=""
+DATA=""
+ADARGS=""
+
+#Loop through all the arguments to the script and concatenate them into $ADARGS.
+#These arguments get passed directly to avrdude.
+while [ $# -ne 0 ]
+do
+ #If this argument is -p, then the next one is the chip name
+ if [ "$1" == "-p" ] && [ "$2" != "" ]
+ then
+ URL=$(echo $URL | sed -e "s/MMCU/$2/")
+ fi
+
+ ADARGS="$ADARGS $1"
+ shift
+done
+
+#Does the user need usage help?
+if [ "$ADARGS" == "" ] || [ "$ADARGS" == "-h" ] || [ "$ADARGS" == "--help" ]
+then
+ echo ""
+ echo "Usage: $0 -c <programmer> -p <partno>"
+ echo ""
+ echo -e "\tExample: $0 -c usbtiny -p ATmega8"
+ echo ""
+ echo -e "Note that the argument supplied to -p is case-sensitive.\nIt should look exactly as it does in the Engbedded Web site's select box.\n"
+ exit
+fi
+
+#Dump fuse info with avrdude and loop through the output word by word
+for WORD in $(avrdude $ADARGS -q -U lfuse:r:-:i -U hfuse:r:-:i -U efuse:r:-:i 2>&1)
+do
+ #Check for the success indicator
+ if [ "$WORD" == "$ADSUCCESS" ]
+ then
+ ADOK=1
+ fi
+
+ #Look for keywords "lfuse", "hfuse", or "efuse". They appear
+ #just before the corresponding fuse values are displayed.
+ if [ $(echo $WORD | grep $LFUSE) ]
+ then
+ FUSE=$LFUSE
+ elif [ $(echo $WORD | grep $HFUSE) ]
+ then
+ FUSE=$HFUSE
+ elif [ $(echo $WORD | grep $EFUSE) ]
+ then
+ FUSE=$EFUSE
+ fi
+
+ #Have we seen one of the fuse keywords?
+ if [ "$FUSE" != "" ]
+ then
+ #Displayed fuse values start with a colon
+ DATA=$(echo $WORD | grep -e "^:")
+
+ if [ "$DATA" != "" ]
+ then
+ #Pull out the fuse byte; 9th and 10th characters in the displayed value
+ DATA=${DATA:9:2}
+
+ #Display the fuse value and update the Engbedded URL with the value
+ echo -e "$FUSE\t0x$DATA"
+ URL=$(echo $URL | sed -e "s/$FUSE/$DATA/")
+
+ #Clear these in order to look for the next fuse
+ FUSE=""
+ DATA=""
+ fi
+ fi
+done
+
+#If there was an error, let the user know.
+#Else, open the Engbedded URL.
+if [ $ADOK -ne 1 ]
+then
+ echo "Avrdude failed! Check your programmer and chip arguments."
+else
+ #Show the URL
+ #echo $URL
+
+ #Open the URL automatically
+ firefox $URL &
+fi
diff --git a/avr-test/ledcube.bin b/avr-test/ledcube.bin
new file mode 100755
index 0000000..ed47c62
--- /dev/null
+++ b/avr-test/ledcube.bin
Binary files differ
diff --git a/avr-test/ledcube.elf b/avr-test/ledcube.elf
new file mode 100755
index 0000000..7143293
--- /dev/null
+++ b/avr-test/ledcube.elf
Binary files differ
diff --git a/avr-test/ledcube.hex b/avr-test/ledcube.hex
new file mode 100644
index 0000000..ac788ca
--- /dev/null
+++ b/avr-test/ledcube.hex
@@ -0,0 +1,277 @@
+:1000000012C02CC02BC070C029C028C027C026C079
+:1000100025C025C023C022C021C020C01FC01EC0D3
+:100020001DC01CC01BC011241FBECFE5D4E0DEBF25
+:10003000CDBF10E0A4E6B0E001C01D92AC3EB10718
+:10004000E1F710E0A0E6B0E0EEE2F1E102C00590D9
+:100050000D92A436B107D9F7D9D067C8D1CF1F9276
+:100060000F920FB60F921124EF92FF920F931F93EE
+:100070002F933F934F935F938F939F93E090E5006F
+:10008000F090E6000091E7001091E800A8019701C8
+:100090002E5F3F4F4F4F5F4F9091EB00892F8A5F4C
+:1000A0008093EB008D3748F097579093EB00A801B1
+:1000B00097012D5F3F4F4F4F5F4F2093E5003093E7
+:1000C000E6004093E7005093E8009F918F915F9185
+:1000D0004F913F912F911F910F91FF90EF900F90B3
+:1000E0000FBE0F901F9018951F920F920FB60F9290
+:1000F00011242F933F934F935F936F938F939F930D
+:10010000AF93BF93EF93FF9385B3877D85BB6091DA
+:10011000E90057E0A62FB0E0E52FF0E033E0EE0F66
+:10012000FF1F3A95E1F7EA0FFB1FEC59FF4F4081A3
+:10013000AC9888B3942F91708E7F982B98BBAC9A13
+:10014000AC9838B3842F90E095958795282F21702F
+:100150003E7F232B28BBAC9AAC9838B395958795F6
+:10016000282F21703E7F232B28BBAC9AAC9838B344
+:1001700095958795282F21703E7F232B28BBAC9A1D
+:10018000AC9838B395958795282F21703E7F232B07
+:1001900028BBAC9AAC9838B395958795282F2170D9
+:1001A0003E7F232B28BBAC9AAC9828B395958795B6
+:1001B00081702E7F822B88BBAC9AAC9888B3441F89
+:1001C0004427441F8E7F482B48BBAC9A515008F0FF
+:1001D000A3CF85B3962F9862887F982B95BB962FD7
+:1001E0009F5F983008F090E09093E900FF91EF91C5
+:1001F000BF91AF919F918F916F915F914F913F917F
+:100200002F910F900FBE0F901F901895EF92FF92B5
+:100210000F931F9312BE83B7836083BF89B781603A
+:1002200089BF8BE083BD85B5856085BD85B5886058
+:1002300085BD14BC89B7806889BF12BA18BA15BACF
+:100240008FEF81BB87BB84BB789420E0EE24E394DE
+:10025000FF24FA9414C080E090E0422F50E0FC01AB
+:1002600063E0EE0FFF1F6A95E1F7E40FF51FEC590D
+:10027000FF4FF08201968830910589F72F5F283073
+:1002800050F3E092A4002091E5003091E600409107
+:10029000E7005091E8008091E5009091E600A09180
+:1002A000E700B091E800821B930BA40BB50B885EAE
+:1002B0009340A040B04078F31092A40084E190E015
+:1002C0006CED70E040ED57E05DD584E690E084D2BF
+:1002D00085E090E061E070E0F7D484E190E068EEC2
+:1002E00073E047D482E090E06AE770E04FEF5FEFA1
+:1002F00024E630E008EE13E09CD1B1D510E088E7A9
+:1003000060E070E046E950E021E030E05ED388E74D
+:1003100061E070E046E950E021E030E056D389E743
+:1003200060E070E046E950E021E030E04ED389E73C
+:1003300061E070E046E950E021E030E046D38AE732
+:1003400060E070E046E950E021E030E03ED38AE72B
+:1003500061E070E046E950E021E030E036D31F5F15
+:100360001A3069F620E077CF75D60895089778F4AB
+:1003700077FD0DC06830710554F457FD08C090E05A
+:10038000483051050CF091E081E0982701C090E0E1
+:10039000892F0895FF920F931F93CF93DF93F82E29
+:1003A0008B01EA01E3DF8823A9F0FE0193E0EE0F61
+:1003B000FF1F9A95E1F7E00FF11FEC59FF4F2081E5
+:1003C00081E090E002C0880F991FFA94E2F78095CF
+:1003D00082238083DF91CF911F910F91FF90089529
+:1003E000FF920F931F93CF93DF93F82E8B01EA01B7
+:1003F000BDDF8823A1F0FE0133E0EE0FFF1F3A9529
+:10040000E1F7E00FF11FEC59FF4F208181E090E010
+:1004100002C0880F991FFA94E2F7282B2083DF91FE
+:10042000CF911F910F91FF900895FF920F931F930B
+:10043000CF93DF93F82E8B01EA0198DF882389F0B0
+:1004400043E0CC0FDD1F4A95E1F7C00FD11FCC5917
+:10045000DF4F888190E002C095958795FA94E2F786
+:100460008170DF91CF911F910F91FF9008952130FE
+:10047000310511F4B5DF08958DDF089540E050E0B7
+:1004800010C0FB01E20FF31FEC59FF4F80832F5F79
+:100490003F4F28303105A9F74F5F5F4F4830510576
+:1004A00049F020E030E0BA01E3E0660F771FEA95FB
+:1004B000E1F7E7CF08950BC020E000000000000046
+:1004C0000000000000002F5F2A35B9F70197009760
+:1004D00099F708952F923F924F925F926F927F9279
+:1004E0009F92AF92BF92CF92DF92EF92FF920F93C3
+:1004F0001F93CF93DF93982E5B01CC24DD2447E03C
+:10050000242E312C8FEFA8168FEFB80611F4760148
+:1005100003C07101EC18FD0800E010E02701089409
+:100520004108510837010894611C711C36C08FEFD7
+:10053000A8168FEFB80611F4C30101C0C201AC01C7
+:100540008AE7981641F4C801BE016FDF282FC80161
+:10055000BE01A70117C089E7981649F4C801BA017E
+:10056000AE0163DF282FC801B701AE010BC088E7D9
+:10057000981651F4CA01BE01A80157DF282FC70100
+:10058000BE01A80130E073DF2196C830D10579F6AD
+:100590000F5F1F4F0830110519F0C0E0D0E0C7CF42
+:1005A0000894C11CD11C88E0C816D10409F0AACF58
+:1005B0008FEFA8168FEFB80619F0EE24FF2403C0C2
+:1005C00037E0E32EF12C00E010E01EC08AE7981619
+:1005D00021F4C801BE01A7010DC089E7981621F4D6
+:1005E000C801B701AE0106C088E7981621F4C7011B
+:1005F000BE01A801CFDE2196C830D10539F70F5FC3
+:100600001F4F0830110519F0C0E0D0E0DFCFDF91B7
+:10061000CF911F910F91FF90EF90DF90CF90BF90FF
+:10062000AF909F907F906F905F904F903F902F90F2
+:1006300008952F923F924F925F926F927F928F9286
+:100640009F92AF92BF92CF92DF92EF92FF920F9361
+:100650001F93DF93CF93CDB7DEB72E970FB6F894E5
+:10066000DEBF0FBECDBF9A8389837C836B835E839D
+:100670004D8338872F831A8709874F5F5F4F21F497
+:1006800097E0292E312C02C02224332489E0682EE1
+:10069000712C89819A81681A790A66DEB30132D495
+:1006A0006C0162DEB3012ED47C014424552475C054
+:1006B0005BDE8C0159DE9C01C80163E070E022D44E
+:1006C00001978C0D9D1D9E878D87181619061CF4A9
+:1006D0008615970514F0DE86CD86C90163E070E0CB
+:1006E00011D48C01015010400E0D1F1D1016110663
+:1006F0001CF4061517050CF087018B816D817E8136
+:10070000E9DE8D849E84AA24BB2430C0EB81FC8169
+:10071000EA37F10521F4C401B601A10115C08B81AE
+:100720009C818937910521F4C401B101A6010CC057
+:10073000EB81FC81E837F10541F44D855E854E0D76
+:100740005F1DC1016B857C854BDE0894E11CF11CAB
+:100750000894C11CD11C89819A81E816F906B4F26B
+:100760000894A11CB11C0894811C911CE981FA8198
+:10077000AE16BF064CF46801EE24FF24C501800FBD
+:10078000911F9C878B87E7CF89859A8594DE089493
+:10079000411C511CCD84DE847801EF81F8854E1612
+:1007A0005F060CF485CF2E960FB6F894DEBF0FBE11
+:1007B000CDBFCF91DF911F910F91FF90EF90DF9010
+:1007C000CF90BF90AF909F908F907F906F905F90F1
+:1007D0004F903F902F900895AF92BF92CF92DF92AB
+:1007E000EF92FF920F931F93CF93DF935C01CC2482
+:1007F000DD242AC0B9DD64E070E084D3EC01EE248E
+:10080000FF2415C0B1DD8C01AFDD9C01C80168E09B
+:1008100070E078D3FC01C90168E070E073D3BC01DB
+:10082000CF0147E050E0DCDD0894E11CF11CEC1640
+:10083000FD0644F388EE93E03EDE8AE76FEF7FEF3C
+:1008400049DE0894C11CD11CCA14DB049CF2DF9160
+:10085000CF911F910F91FF90EF90DF90CF90BF90BD
+:10086000AF9008957F928F929F92AF92BF92CF9256
+:10087000DF92EF92FF920F931F93CF93DF93E82EB7
+:10088000F62E742E6901C0E0D0E0F7E08F2E912C97
+:10089000E8E0AE2EB12C87E0781661F484010C1BE1
+:1008A0001D0BA5014C1B5D0B8E2D90E06F2D70E094
+:1008B00071DD09C0AE01415050408E2D90E06F2D8A
+:1008C00070E068DD8E018E2D90E06F2D70E0A80144
+:1008D00087DDC601F0DD2196C830D105E1F6DF9154
+:1008E000CF911F910F91FF90EF90DF90CF90BF902D
+:1008F000AF909F908F907F9008954F925F926F92EC
+:100900007F929F92AF92BF92CF92DF92EF92FF922F
+:100910000F931F93CF93DF93982E162F072F3A0133
+:1009200080E0ACDD212F302FC9016C01C0E0D0E0A8
+:1009300057E0452E512C34C06114710431F0F5019B
+:100940008081A201481B510904C0F7018081482F12
+:1009500050E0FAE79F1619F4CE01B8010DC089E7FF
+:10096000981621F4CE01BA01A80106C098E799169D
+:1009700021F4CA01B801AE0133DD0F5F1F4F0894A7
+:10098000A11CB11C0894E11CF11C08301105A1F652
+:100990002196E8E0F0E0CE0EDF1EC830D10529F048
+:1009A0005601760100E010E0C7CFDF91CF911F9193
+:1009B0000F91FF90EF90DF90CF90BF90AF909F90FE
+:1009C0007F906F905F904F9008952F923F924F923B
+:1009D0005F926F927F928F929F92AF92BF92CF92CF
+:1009E000DF92EF92FF920F931F93DF93CF93CDB7D8
+:1009F000DEB7C158D0400FB6F894DEBF0FBECDBFF2
+:100A0000CF57DF4F8883C158D0402B013A014901AD
+:100A100071E4A72EB12CAC0EBD1EF50161E8C62E07
+:100A2000D12CCC0EDD1E1192EC15FD05E1F700E096
+:100A300010E01E010894211C311C81E088169104ED
+:100A4000B9F412C091DC60E470E05CD2E1E4F0E063
+:100A5000EC0FFD1FE80FF91F8081882399F70F5FC6
+:100A60001F4F91E0908316C0003411055CF312C053
+:100A700082E08816910471F4003411055CF4E1E41D
+:100A8000F0E0EC0FFD1FE00FF11F80818F5F80838E
+:100A90000F5F1F4FF501EE24FF249081892F8150B5
+:100AA000863010F49F5F90838081873019F408941A
+:100AB000E11CF11C3196EC15FD0579F7D101F5012A
+:100AC00080814114510419F097E0981B892F8C9371
+:100AD00031961196EC15FD0599F7C301ECDCCF5763
+:100AE000DF4F8881C158D040B10140E050E005DFC0
+:100AF00082B394E0892782BB80E4E816F10409F010
+:100B00009CCFCF57DF4F0FB6F894DEBF0FBECDBFDF
+:100B1000CF91DF911F910F91FF90EF90DF90CF90D9
+:100B2000BF90AF909F908F907F906F905F904F900D
+:100B30003F902F900895AC01DC01FB0120E030E0F4
+:100B40009C918081981710F49F5F9C939C91808169
+:100B5000891710F491509C932F5F3F4F1196319657
+:100B60002034310569F78AE7BA0140E050E0C5DE7C
+:100B700008952F923F924F925F926F927F928F9241
+:100B80009F92AF92BF92CF92DF92EF92FF920F931C
+:100B90001F93DF93CF93CDB7DEB7C058D0400FB6C9
+:100BA000F894DEBF0FBECDBF2C017B0100E010E04A
+:100BB0005E010894A11CB11C24E0922E91E4C92E80
+:100BC000D12CCC0EDD1EF501E00FF11F9082CCDBA5
+:100BD000F601E00FF11F68E070E094D180830F5FB1
+:100BE0001F4F0034110579F700E010E081E4A82ED2
+:100BF000B12CAC0EBD1E6E010894C11CD11C370176
+:100C0000C601B5014AE797DFC30155DC0F5F1F4FEF
+:100C100008301105A9F75701AA0CBB1CAA0CBB1C74
+:100C2000CC24DD24A1E48A2E912C8C0E9D1E1E0165
+:100C30000894211C311C2BC000E010E0C101B4015C
+:100C40004AE779DFC30137DC0F5F1F4F083011051A
+:100C5000A9F7C50130DCEE24FF2486DB8C0184DBA0
+:100C60009C01C80160E470E04DD1F401E80FF91F68
+:100C7000C90168E070E046D180830894E11CF11C52
+:100C800080E2E816F10449F70894C11CD11CC41491
+:100C9000D50494F2C058DF4F0FB6F894DEBF0FBEF4
+:100CA000CDBFCF91DF911F910F91FF90EF90DF901B
+:100CB000CF90BF90AF909F908F907F906F905F90FC
+:100CC0004F903F902F9008958F929F92AF92BF9236
+:100CD000CF92DF92EF92FF920F931F93CF93DF9308
+:100CE0004C018B016130710511F480E001C08FEF80
+:100CF000C5DBC0E0D0E038DB68E070E003D1B82E9F
+:100D0000A92E32DB68E070E0FDD0D82EC92E2CDB96
+:100D100068E070E0F7D0F82EE92E0115110551F4C6
+:100D20008B2D9A2D6D2D7C2D4F2D5E2D7EDB8130F0
+:100D300011F70CC001301105F1F68B2D9A2D6D2D98
+:100D40007C2D4F2D5E2D71DB8823A9F68B2D9A2DDE
+:100D50006D2D7C2D4F2D5E2D980189DBC401ABDB01
+:100D6000219681E0CF3FD80731F6DF91CF911F91D7
+:100D70000F91FF90EF90DF90CF90BF90AF909F903A
+:100D80008F9008956F927F928F929F92AF92BF92B1
+:100D9000DF92EF92FF920F931F93CF93DF933C016B
+:100DA0005B014A0180E06ADB00E010E01CC0DCDA95
+:100DB00062E070E0A7D0AC0133E0440F551F3A95D4
+:100DC000E1F7481B590BC801BE010ADB2196C83068
+:100DD000D10569F70F5F1F4F0830110521F4DD249D
+:100DE000EE24FF2429C0C0E0D0E0E1CFBDDAEC0161
+:100DF000BBDA68E070E086D0082F8E15E1F0CE01F6
+:100E000068E070E07FD0182F8D15A9F090E0602F7A
+:100E100070E040E050E009DB882321F0812F602F53
+:100E200040E003C0812F602F47E095011BDDC40126
+:100E300042DBD12EE02EF3948F2D90E0861597059E
+:100E4000ACF2DF91CF911F910F91FF90EF90DF9067
+:100E5000BF90AF909F908F907F906F900895EF928A
+:100E6000FF920F931F93CF93DF9380E007DB00E0A7
+:100E700010E04FEEE42E42E0F42E3AC080E0FEDABD
+:100E8000CE0119DB8FEFFADA84E690E014DBCE01B5
+:100E900066EF7FEF37D088EE93E034D06F5070402C
+:100EA000C60FD71F1C161D064CF388EE93E003DB1C
+:100EB000CEEED2E080E0E2DAC7018C1B9D0BFBDABC
+:100EC0008FEFDCDA84E690E0F6DACE0166EF7FEFB2
+:100ED00019D088EE93E016D06F507040C60FD71F20
+:100EE0001C161D063CF30F5F1F4F0230110519F051
+:100EF000CEEED2E0C3CFDF91CF911F910F91FF9043
+:100F0000EF90089597FB092E07260AD077FD04D0AD
+:100F10000CD006D000201AF4709561957F4F08958B
+:100F2000F6F7909581959F4F0895AA1BBB1B51E141
+:100F300007C0AA1FBB1FA617B70710F0A61BB70B49
+:100F4000881F991F5A95A9F780959095BC01CD01EE
+:100F500008952F923F924F925F926F927F928F925D
+:100F60009F92AF92BF92CF92DF92EF92FF920F9338
+:100F70001F93CF93DF93CDB7DEB7CA1BDB0B0FB642
+:100F8000F894DEBF0FBECDBF09942A8839884888FF
+:100F90005F846E847D848C849B84AA84B984C88495
+:100FA000DF80EE80FD800C811B81AA81B981CE0F8C
+:100FB000D11D0FB6F894DEBF0FBECDBFED01089571
+:100FC000A0E0B0E0E5EEF7E0CCCFEC01A880B9807E
+:100FD000CA80DB80A114B104C104D10441F484E2CD
+:100FE000A82E89EDB82E8BE5C82E87E0D82EC60135
+:100FF000B5012DE133EF41E050E05AD027EA31E46A
+:1010000040E050E036D07B018C01C601B5012DE1F6
+:1010100033EF41E050E04CD0CA01B9012CEE34EF7F
+:101020004FEF5FEF26D06E0D7F1D801F911F97FF42
+:1010300004C06150704080409048688379838A83FF
+:101040009B839B013F77C901CDB7DEB7EAE0A5CF0F
+:10105000B7DF089580E690E0B3DF0895A0E0B0E048
+:101060008093600090936100A0936200B09363004E
+:101070000895629FD001739FF001829FE00DF11DE2
+:10108000649FE00DF11D929FF00D839FF00D749F02
+:10109000F00D659FF00D9927729FB00DE11DF91FAE
+:1010A000639FB00DE11DF91FBD01CF01112408950B
+:1010B00097FB092E05260ED057FD04D014D00AD078
+:1010C000001C38F450954095309521953F4F4F4F77
+:1010D0005F4F0895F6F790958095709561957F4FD5
+:1010E0008F4F9F4F0895A1E21A2EAA1BBB1BFD0133
+:1010F0000DC0AA1FBB1FEE1FFF1FA217B307E407F7
+:10110000F50720F0A21BB30BE40BF50B661F771F4E
+:10111000881F991F1A9469F760957095809590952E
+:0E1120009B01AC01BD01CF010895F894FFCFF3
+:04112E0001000000BC
+:00000001FF
diff --git a/avr-test/ledcube.lst b/avr-test/ledcube.lst
new file mode 100644
index 0000000..6fde88b
--- /dev/null
+++ b/avr-test/ledcube.lst
@@ -0,0 +1,3367 @@
+
+ledcube.elf: file format elf32-avr
+
+Sections:
+Idx Name Size VMA LMA File off Algn
+ 0 .text 0000112e 00000000 00000000 00000094 2**1
+ CONTENTS, ALLOC, LOAD, READONLY, CODE
+ 1 .data 00000004 00800060 0000112e 000011c2 2**0
+ CONTENTS, ALLOC, LOAD, DATA
+ 2 .bss 00000088 00800064 00800064 000011c6 2**0
+ ALLOC
+ 3 .stab 00004284 00000000 00000000 000011c8 2**2
+ CONTENTS, READONLY, DEBUGGING
+ 4 .stabstr 00001cbd 00000000 00000000 0000544c 2**0
+ CONTENTS, READONLY, DEBUGGING
+
+Disassembly of section .text:
+
+00000000 <__vectors>:
+ 0: 12 c0 rjmp .+36 ; 0x26 <__ctors_end>
+ 2: 2c c0 rjmp .+88 ; 0x5c <__bad_interrupt>
+ 4: 2b c0 rjmp .+86 ; 0x5c <__bad_interrupt>
+ 6: 70 c0 rjmp .+224 ; 0xe8 <__vector_3>
+ 8: 29 c0 rjmp .+82 ; 0x5c <__bad_interrupt>
+ a: 28 c0 rjmp .+80 ; 0x5c <__bad_interrupt>
+ c: 27 c0 rjmp .+78 ; 0x5c <__bad_interrupt>
+ e: 26 c0 rjmp .+76 ; 0x5c <__bad_interrupt>
+ 10: 25 c0 rjmp .+74 ; 0x5c <__bad_interrupt>
+ 12: 25 c0 rjmp .+74 ; 0x5e <__vector_9>
+ 14: 23 c0 rjmp .+70 ; 0x5c <__bad_interrupt>
+ 16: 22 c0 rjmp .+68 ; 0x5c <__bad_interrupt>
+ 18: 21 c0 rjmp .+66 ; 0x5c <__bad_interrupt>
+ 1a: 20 c0 rjmp .+64 ; 0x5c <__bad_interrupt>
+ 1c: 1f c0 rjmp .+62 ; 0x5c <__bad_interrupt>
+ 1e: 1e c0 rjmp .+60 ; 0x5c <__bad_interrupt>
+ 20: 1d c0 rjmp .+58 ; 0x5c <__bad_interrupt>
+ 22: 1c c0 rjmp .+56 ; 0x5c <__bad_interrupt>
+ 24: 1b c0 rjmp .+54 ; 0x5c <__bad_interrupt>
+
+00000026 <__ctors_end>:
+ 26: 11 24 eor r1, r1
+ 28: 1f be out 0x3f, r1 ; 63
+ 2a: cf e5 ldi r28, 0x5F ; 95
+ 2c: d4 e0 ldi r29, 0x04 ; 4
+ 2e: de bf out 0x3e, r29 ; 62
+ 30: cd bf out 0x3d, r28 ; 61
+
+00000032 <__do_clear_bss>:
+ 32: 10 e0 ldi r17, 0x00 ; 0
+ 34: a4 e6 ldi r26, 0x64 ; 100
+ 36: b0 e0 ldi r27, 0x00 ; 0
+ 38: 01 c0 rjmp .+2 ; 0x3c <.do_clear_bss_start>
+
+0000003a <.do_clear_bss_loop>:
+ 3a: 1d 92 st X+, r1
+
+0000003c <.do_clear_bss_start>:
+ 3c: ac 3e cpi r26, 0xEC ; 236
+ 3e: b1 07 cpc r27, r17
+ 40: e1 f7 brne .-8 ; 0x3a <.do_clear_bss_loop>
+
+00000042 <__do_copy_data>:
+ 42: 10 e0 ldi r17, 0x00 ; 0
+ 44: a0 e6 ldi r26, 0x60 ; 96
+ 46: b0 e0 ldi r27, 0x00 ; 0
+ 48: ee e2 ldi r30, 0x2E ; 46
+ 4a: f1 e1 ldi r31, 0x11 ; 17
+ 4c: 02 c0 rjmp .+4 ; 0x52 <.do_copy_data_start>
+
+0000004e <.do_copy_data_loop>:
+ 4e: 05 90 lpm r0, Z+
+ 50: 0d 92 st X+, r0
+
+00000052 <.do_copy_data_start>:
+ 52: a4 36 cpi r26, 0x64 ; 100
+ 54: b1 07 cpc r27, r17
+ 56: d9 f7 brne .-10 ; 0x4e <.do_copy_data_loop>
+ 58: d9 d0 rcall .+434 ; 0x20c <main>
+ 5a: 67 c8 rjmp .-3890 ; 0xfffff12a <__eeprom_end+0xff7ef12a>
+
+0000005c <__bad_interrupt>:
+ 5c: d1 cf rjmp .-94 ; 0x0 <__vectors>
+
+0000005e <__vector_9>:
+//volatile uint32_t timer0_overflow_count = 0;
+volatile uint32_t timer0_millis = 0;
+//static uint8_t timer0_fract = 0;
+
+
+ISR(TIMER0_OVF_vect)
+ 5e: 1f 92 push r1
+ 60: 0f 92 push r0
+ 62: 0f b6 in r0, 0x3f ; 63
+ 64: 0f 92 push r0
+ 66: 11 24 eor r1, r1
+ 68: ef 92 push r14
+ 6a: ff 92 push r15
+ 6c: 0f 93 push r16
+ 6e: 1f 93 push r17
+ 70: 2f 93 push r18
+ 72: 3f 93 push r19
+ 74: 4f 93 push r20
+ 76: 5f 93 push r21
+ 78: 8f 93 push r24
+ 7a: 9f 93 push r25
+{
+ // copy these to local variables so they can be stored in registers
+ // (volatile variables must be read from memory on every access)
+ uint32_t m = timer0_millis;
+ 7c: e0 90 e5 00 lds r14, 0x00E5
+ 80: f0 90 e6 00 lds r15, 0x00E6
+ 84: 00 91 e7 00 lds r16, 0x00E7
+ 88: 10 91 e8 00 lds r17, 0x00E8
+ //uint8_t f = timer0_fract;
+ static uint8_t timer0_fract = 0;
+
+ m += MILLIS_INC;
+ 8c: a8 01 movw r20, r16
+ 8e: 97 01 movw r18, r14
+ 90: 2e 5f subi r18, 0xFE ; 254
+ 92: 3f 4f sbci r19, 0xFF ; 255
+ 94: 4f 4f sbci r20, 0xFF ; 255
+ 96: 5f 4f sbci r21, 0xFF ; 255
+ //f += FRACT_INC;
+ timer0_fract += FRACT_INC;
+ 98: 90 91 eb 00 lds r25, 0x00EB
+ 9c: 89 2f mov r24, r25
+ 9e: 8a 5f subi r24, 0xFA ; 250
+ a0: 80 93 eb 00 sts 0x00EB, r24
+ //if (f >= FRACT_MAX) {
+ if (timer0_fract >= FRACT_MAX) {
+ a4: 8d 37 cpi r24, 0x7D ; 125
+ a6: 48 f0 brcs .+18 ; 0xba <__vector_9+0x5c>
+ //f -= FRACT_MAX;
+ timer0_fract -= FRACT_MAX;
+ a8: 97 57 subi r25, 0x77 ; 119
+ aa: 90 93 eb 00 sts 0x00EB, r25
+ ++m;
+ ae: a8 01 movw r20, r16
+ b0: 97 01 movw r18, r14
+ b2: 2d 5f subi r18, 0xFD ; 253
+ b4: 3f 4f sbci r19, 0xFF ; 255
+ b6: 4f 4f sbci r20, 0xFF ; 255
+ b8: 5f 4f sbci r21, 0xFF ; 255
+ }
+
+ //timer0_fract = f;
+ timer0_millis = m;
+ ba: 20 93 e5 00 sts 0x00E5, r18
+ be: 30 93 e6 00 sts 0x00E6, r19
+ c2: 40 93 e7 00 sts 0x00E7, r20
+ c6: 50 93 e8 00 sts 0x00E8, r21
+ //if (timer0_overflow_count & 0x1)
+ //if (m - last_time >= 5) {
+ //debounce_keys(); // called nearly each 2ms (0,002048s)
+ //last_time = m;
+ //}
+}
+ ca: 9f 91 pop r25
+ cc: 8f 91 pop r24
+ ce: 5f 91 pop r21
+ d0: 4f 91 pop r20
+ d2: 3f 91 pop r19
+ d4: 2f 91 pop r18
+ d6: 1f 91 pop r17
+ d8: 0f 91 pop r16
+ da: ff 90 pop r15
+ dc: ef 90 pop r14
+ de: 0f 90 pop r0
+ e0: 0f be out 0x3f, r0 ; 63
+ e2: 0f 90 pop r0
+ e4: 1f 90 pop r1
+ e6: 18 95 reti
+
+000000e8 <__vector_3>:
+// current_layer = current_layer_ & 0x07;
+//
+// PORTC |= 0x28; // layer and latch high
+//}
+
+ISR(TIMER2_COMP_vect)
+ e8: 1f 92 push r1
+ ea: 0f 92 push r0
+ ec: 0f b6 in r0, 0x3f ; 63
+ ee: 0f 92 push r0
+ f0: 11 24 eor r1, r1
+ f2: 2f 93 push r18
+ f4: 3f 93 push r19
+ f6: 4f 93 push r20
+ f8: 5f 93 push r21
+ fa: 6f 93 push r22
+ fc: 8f 93 push r24
+ fe: 9f 93 push r25
+ 100: af 93 push r26
+ 102: bf 93 push r27
+ 104: ef 93 push r30
+ 106: ff 93 push r31
+{
+ //if (!in_wait) return;
+ PORTC &= ~0x28; // layer and latch low
+ 108: 85 b3 in r24, 0x15 ; 21
+ 10a: 87 7d andi r24, 0xD7 ; 215
+ 10c: 85 bb out 0x15, r24 ; 21
+ unsigned char current_layer_ = current_layer;
+ 10e: 60 91 e9 00 lds r22, 0x00E9
+ 112: 57 e0 ldi r21, 0x07 ; 7
+
+ for (unsigned char j = 7; j < 255; --j) {
+ //for (char j = 0; j < 4; ++j) {
+ unsigned char val = cube[j][current_layer_];
+ 114: a6 2f mov r26, r22
+ 116: b0 e0 ldi r27, 0x00 ; 0
+ 118: e5 2f mov r30, r21
+ 11a: f0 e0 ldi r31, 0x00 ; 0
+ 11c: 33 e0 ldi r19, 0x03 ; 3
+ 11e: ee 0f add r30, r30
+ 120: ff 1f adc r31, r31
+ 122: 3a 95 dec r19
+ 124: e1 f7 brne .-8 ; 0x11e <__vector_3+0x36>
+ 126: ea 0f add r30, r26
+ 128: fb 1f adc r31, r27
+ 12a: ec 59 subi r30, 0x9C ; 156
+ 12c: ff 4f sbci r31, 0xFF ; 255
+ 12e: 40 81 ld r20, Z
+ PORTC &= ~0x10;
+ 130: ac 98 cbi 0x15, 4 ; 21
+ PORTB = (PORTB & ~0x01) | ((val ) & 0x01);
+ 132: 88 b3 in r24, 0x18 ; 24
+ 134: 94 2f mov r25, r20
+ 136: 91 70 andi r25, 0x01 ; 1
+ 138: 8e 7f andi r24, 0xFE ; 254
+ 13a: 98 2b or r25, r24
+ 13c: 98 bb out 0x18, r25 ; 24
+ PORTC |= 0x10;
+ 13e: ac 9a sbi 0x15, 4 ; 21
+ PORTC &= ~0x10;
+ 140: ac 98 cbi 0x15, 4 ; 21
+ PORTB = (PORTB & ~0x01) | ((val >> 1) & 0x01);
+ 142: 38 b3 in r19, 0x18 ; 24
+ 144: 84 2f mov r24, r20
+ 146: 90 e0 ldi r25, 0x00 ; 0
+ 148: 95 95 asr r25
+ 14a: 87 95 ror r24
+ 14c: 28 2f mov r18, r24
+ 14e: 21 70 andi r18, 0x01 ; 1
+ 150: 3e 7f andi r19, 0xFE ; 254
+ 152: 23 2b or r18, r19
+ 154: 28 bb out 0x18, r18 ; 24
+ PORTC |= 0x10;
+ 156: ac 9a sbi 0x15, 4 ; 21
+ PORTC &= ~0x10;
+ 158: ac 98 cbi 0x15, 4 ; 21
+ PORTB = (PORTB & ~0x01) | ((val >> 2) & 0x01);
+ 15a: 38 b3 in r19, 0x18 ; 24
+ 15c: 95 95 asr r25
+ 15e: 87 95 ror r24
+ 160: 28 2f mov r18, r24
+ 162: 21 70 andi r18, 0x01 ; 1
+ 164: 3e 7f andi r19, 0xFE ; 254
+ 166: 23 2b or r18, r19
+ 168: 28 bb out 0x18, r18 ; 24
+ PORTC |= 0x10;
+ 16a: ac 9a sbi 0x15, 4 ; 21
+ PORTC &= ~0x10;
+ 16c: ac 98 cbi 0x15, 4 ; 21
+ PORTB = (PORTB & ~0x01) | ((val >> 3) & 0x01);
+ 16e: 38 b3 in r19, 0x18 ; 24
+ 170: 95 95 asr r25
+ 172: 87 95 ror r24
+ 174: 28 2f mov r18, r24
+ 176: 21 70 andi r18, 0x01 ; 1
+ 178: 3e 7f andi r19, 0xFE ; 254
+ 17a: 23 2b or r18, r19
+ 17c: 28 bb out 0x18, r18 ; 24
+ PORTC |= 0x10;
+ 17e: ac 9a sbi 0x15, 4 ; 21
+ PORTC &= ~0x10;
+ 180: ac 98 cbi 0x15, 4 ; 21
+ PORTB = (PORTB & ~0x01) | ((val >> 4) & 0x01);
+ 182: 38 b3 in r19, 0x18 ; 24
+ 184: 95 95 asr r25
+ 186: 87 95 ror r24
+ 188: 28 2f mov r18, r24
+ 18a: 21 70 andi r18, 0x01 ; 1
+ 18c: 3e 7f andi r19, 0xFE ; 254
+ 18e: 23 2b or r18, r19
+ 190: 28 bb out 0x18, r18 ; 24
+ PORTC |= 0x10;
+ 192: ac 9a sbi 0x15, 4 ; 21
+ PORTC &= ~0x10;
+ 194: ac 98 cbi 0x15, 4 ; 21
+ PORTB = (PORTB & ~0x01) | ((val >> 5) & 0x01);
+ 196: 38 b3 in r19, 0x18 ; 24
+ 198: 95 95 asr r25
+ 19a: 87 95 ror r24
+ 19c: 28 2f mov r18, r24
+ 19e: 21 70 andi r18, 0x01 ; 1
+ 1a0: 3e 7f andi r19, 0xFE ; 254
+ 1a2: 23 2b or r18, r19
+ 1a4: 28 bb out 0x18, r18 ; 24
+ PORTC |= 0x10;
+ 1a6: ac 9a sbi 0x15, 4 ; 21
+ PORTC &= ~0x10;
+ 1a8: ac 98 cbi 0x15, 4 ; 21
+ PORTB = (PORTB & ~0x01) | ((val >> 6) & 0x01);
+ 1aa: 28 b3 in r18, 0x18 ; 24
+ 1ac: 95 95 asr r25
+ 1ae: 87 95 ror r24
+ 1b0: 81 70 andi r24, 0x01 ; 1
+ 1b2: 2e 7f andi r18, 0xFE ; 254
+ 1b4: 82 2b or r24, r18
+ 1b6: 88 bb out 0x18, r24 ; 24
+ PORTC |= 0x10;
+ 1b8: ac 9a sbi 0x15, 4 ; 21
+ PORTC &= ~0x10;
+ 1ba: ac 98 cbi 0x15, 4 ; 21
+ PORTB = (PORTB & ~0x01) | ((val >> 7) & 0x01);
+ 1bc: 88 b3 in r24, 0x18 ; 24
+ 1be: 44 1f adc r20, r20
+ 1c0: 44 27 eor r20, r20
+ 1c2: 44 1f adc r20, r20
+ 1c4: 8e 7f andi r24, 0xFE ; 254
+ 1c6: 48 2b or r20, r24
+ 1c8: 48 bb out 0x18, r20 ; 24
+ //PORTD = val;
+ PORTC |= 0x10;
+ 1ca: ac 9a sbi 0x15, 4 ; 21
+{
+ //if (!in_wait) return;
+ PORTC &= ~0x28; // layer and latch low
+ unsigned char current_layer_ = current_layer;
+
+ for (unsigned char j = 7; j < 255; --j) {
+ 1cc: 51 50 subi r21, 0x01 ; 1
+ 1ce: 08 f0 brcs .+2 ; 0x1d2 <__vector_3+0xea>
+ 1d0: a3 cf rjmp .-186 ; 0x118 <__vector_3+0x30>
+ PORTB = (PORTB & ~0x01) | ((val >> 7) & 0x01);
+ //PORTD = val;
+ PORTC |= 0x10;
+ }
+
+ PORTC = (PORTC & ~0x07) | current_layer_ | 0x28;
+ 1d2: 85 b3 in r24, 0x15 ; 21
+ 1d4: 96 2f mov r25, r22
+ 1d6: 98 62 ori r25, 0x28 ; 40
+ 1d8: 88 7f andi r24, 0xF8 ; 248
+ 1da: 98 2b or r25, r24
+ 1dc: 95 bb out 0x15, r25 ; 21
+ ++current_layer_;
+ 1de: 96 2f mov r25, r22
+ 1e0: 9f 5f subi r25, 0xFF ; 255
+ if (current_layer_ > 7) current_layer_ = 0;
+ 1e2: 98 30 cpi r25, 0x08 ; 8
+ 1e4: 08 f0 brcs .+2 ; 0x1e8 <__vector_3+0x100>
+ 1e6: 90 e0 ldi r25, 0x00 ; 0
+ //current_layer = current_layer_ & 0x07;
+ current_layer = current_layer_;
+ 1e8: 90 93 e9 00 sts 0x00E9, r25
+
+ //PORTC |= 0x28; // layer and latch high
+}
+ 1ec: ff 91 pop r31
+ 1ee: ef 91 pop r30
+ 1f0: bf 91 pop r27
+ 1f2: af 91 pop r26
+ 1f4: 9f 91 pop r25
+ 1f6: 8f 91 pop r24
+ 1f8: 6f 91 pop r22
+ 1fa: 5f 91 pop r21
+ 1fc: 4f 91 pop r20
+ 1fe: 3f 91 pop r19
+ 200: 2f 91 pop r18
+ 202: 0f 90 pop r0
+ 204: 0f be out 0x3f, r0 ; 63
+ 206: 0f 90 pop r0
+ 208: 1f 90 pop r1
+ 20a: 18 95 reti
+
+0000020c <main>:
+ *****************************************************************************/
+#include "main.h"
+#include "effect.h"
+#include "draw.h"
+
+int main()
+ 20c: ef 92 push r14
+ 20e: ff 92 push r15
+ 210: 0f 93 push r16
+ 212: 1f 93 push r17
+ * Initialisation
+ * =======================================================================
+ */
+
+ //*** init time management
+ TCNT0 = 0; // init timer count to 0
+ 214: 12 be out 0x32, r1 ; 50
+ TCCR0 |= 0x03; // prescaler: 64
+ 216: 83 b7 in r24, 0x33 ; 51
+ 218: 83 60 ori r24, 0x03 ; 3
+ 21a: 83 bf out 0x33, r24 ; 51
+ TIMSK |= 0x01; // enable timer 0 overflow interrupt
+ 21c: 89 b7 in r24, 0x39 ; 57
+ 21e: 81 60 ori r24, 0x01 ; 1
+ 220: 89 bf out 0x39, r24 ; 57
+
+ // Timer 2
+ // Frame buffer interrupt
+ // 14745600/128/11 = 10472.72 interrupts per second
+ // 10472.72/8 = 1309 frames per second
+ OCR2 = 11; // interrupt at counter = 10
+ 222: 8b e0 ldi r24, 0x0B ; 11
+ 224: 83 bd out 0x23, r24 ; 35
+ TCCR2 |= (1 << CS20) | (0 << CS21) | (1 << CS22); // Prescaler = 128.
+ 226: 85 b5 in r24, 0x25 ; 37
+ 228: 85 60 ori r24, 0x05 ; 5
+ 22a: 85 bd out 0x25, r24 ; 37
+ TCCR2 |= (1 << WGM21); // CTC mode. Reset counter when OCR2 is reached.
+ 22c: 85 b5 in r24, 0x25 ; 37
+ 22e: 88 60 ori r24, 0x08 ; 8
+ 230: 85 bd out 0x25, r24 ; 37
+ TCNT2 = 0x00; // initial counter value = 0;
+ 232: 14 bc out 0x24, r1 ; 36
+ TIMSK |= (1 << OCIE2); // Enable CTC interrupt
+ 234: 89 b7 in r24, 0x39 ; 57
+ 236: 80 68 ori r24, 0x80 ; 128
+ 238: 89 bf out 0x39, r24 ; 57
+
+ PORTD = 0;
+ 23a: 12 ba out 0x12, r1 ; 18
+ PORTB = 0;
+ 23c: 18 ba out 0x18, r1 ; 24
+ PORTC = 0;
+ 23e: 15 ba out 0x15, r1 ; 21
+ DDRD = 0xff;
+ 240: 8f ef ldi r24, 0xFF ; 255
+ 242: 81 bb out 0x11, r24 ; 17
+ DDRB = 0xff;
+ 244: 87 bb out 0x17, r24 ; 23
+ DDRC = 0xff;
+ 246: 84 bb out 0x14, r24 ; 20
+
+ //*** set interupts
+ sei();
+ 248: 78 94 sei
+ 24a: 20 e0 ldi r18, 0x00 ; 0
+ return timer0_millis;
+}
+
+void delay(uint32_t ms)
+{
+ in_wait = true;
+ 24c: ee 24 eor r14, r14
+ 24e: e3 94 inc r14
+
+ //clear_led();
+ //delay_ms(1000);
+ for (unsigned char z = 0; z < 8; ++z) {
+ for (unsigned char y = 0; y < 8; ++y) {
+ cube[y][z] = 0xFF;
+ 250: ff 24 eor r15, r15
+ 252: fa 94 dec r15
+ 254: 14 c0 rjmp .+40 ; 0x27e <main+0x72>
+ DDRD = 0xff;
+ DDRB = 0xff;
+ DDRC = 0xff;
+
+ //*** set interupts
+ sei();
+ 256: 80 e0 ldi r24, 0x00 ; 0
+ 258: 90 e0 ldi r25, 0x00 ; 0
+
+ //clear_led();
+ //delay_ms(1000);
+ for (unsigned char z = 0; z < 8; ++z) {
+ for (unsigned char y = 0; y < 8; ++y) {
+ cube[y][z] = 0xFF;
+ 25a: 42 2f mov r20, r18
+ 25c: 50 e0 ldi r21, 0x00 ; 0
+ 25e: fc 01 movw r30, r24
+ 260: 63 e0 ldi r22, 0x03 ; 3
+ 262: ee 0f add r30, r30
+ 264: ff 1f adc r31, r31
+ 266: 6a 95 dec r22
+ 268: e1 f7 brne .-8 ; 0x262 <main+0x56>
+ 26a: e4 0f add r30, r20
+ 26c: f5 1f adc r31, r21
+ 26e: ec 59 subi r30, 0x9C ; 156
+ 270: ff 4f sbci r31, 0xFF ; 255
+ 272: f0 82 st Z, r15
+ 274: 01 96 adiw r24, 0x01 ; 1
+ for (;;) {
+
+ //clear_led();
+ //delay_ms(1000);
+ for (unsigned char z = 0; z < 8; ++z) {
+ for (unsigned char y = 0; y < 8; ++y) {
+ 276: 88 30 cpi r24, 0x08 ; 8
+ 278: 91 05 cpc r25, r1
+ 27a: 89 f7 brne .-30 ; 0x25e <main+0x52>
+
+ for (;;) {
+
+ //clear_led();
+ //delay_ms(1000);
+ for (unsigned char z = 0; z < 8; ++z) {
+ 27c: 2f 5f subi r18, 0xFF ; 255
+ 27e: 28 30 cpi r18, 0x08 ; 8
+ 280: 50 f3 brcs .-44 ; 0x256 <main+0x4a>
+ return timer0_millis;
+}
+
+void delay(uint32_t ms)
+{
+ in_wait = true;
+ 282: e0 92 a4 00 sts 0x00A4, r14
+}
+*/
+
+inline uint32_t millis()
+{
+ return timer0_millis;
+ 286: 20 91 e5 00 lds r18, 0x00E5
+ 28a: 30 91 e6 00 lds r19, 0x00E6
+ 28e: 40 91 e7 00 lds r20, 0x00E7
+ 292: 50 91 e8 00 lds r21, 0x00E8
+ 296: 80 91 e5 00 lds r24, 0x00E5
+ 29a: 90 91 e6 00 lds r25, 0x00E6
+ 29e: a0 91 e7 00 lds r26, 0x00E7
+ 2a2: b0 91 e8 00 lds r27, 0x00E8
+
+void delay(uint32_t ms)
+{
+ in_wait = true;
+ uint32_t time1 = millis();
+ while ((millis()) - time1 < ms);
+ 2a6: 82 1b sub r24, r18
+ 2a8: 93 0b sbc r25, r19
+ 2aa: a4 0b sbc r26, r20
+ 2ac: b5 0b sbc r27, r21
+ 2ae: 88 5e subi r24, 0xE8 ; 232
+ 2b0: 93 40 sbci r25, 0x03 ; 3
+ 2b2: a0 40 sbci r26, 0x00 ; 0
+ 2b4: b0 40 sbci r27, 0x00 ; 0
+ 2b6: 78 f3 brcs .-34 ; 0x296 <main+0x8a>
+ in_wait = false;
+ 2b8: 10 92 a4 00 sts 0x00A4, r1
+ delay(1000);
+
+ // Show the effects in a predefined order
+ //for (char i=0; i<EFFECTS_TOTAL; i++)
+ //launch_effect(i);
+ sendvoxels_rand_z(20,220,2000);
+ 2bc: 84 e1 ldi r24, 0x14 ; 20
+ 2be: 90 e0 ldi r25, 0x00 ; 0
+ 2c0: 6c ed ldi r22, 0xDC ; 220
+ 2c2: 70 e0 ldi r23, 0x00 ; 0
+ 2c4: 40 ed ldi r20, 0xD0 ; 208
+ 2c6: 57 e0 ldi r21, 0x07 ; 7
+ 2c8: 5d d5 rcall .+2746 ; 0xd84 <_Z17sendvoxels_rand_ziii>
+ effect_rain(100);
+ 2ca: 84 e6 ldi r24, 0x64 ; 100
+ 2cc: 90 e0 ldi r25, 0x00 ; 0
+ 2ce: 84 d2 rcall .+1288 ; 0x7d8 <_Z11effect_raini>
+ effect_random_filler(5,1);
+ 2d0: 85 e0 ldi r24, 0x05 ; 5
+ 2d2: 90 e0 ldi r25, 0x00 ; 0
+ 2d4: 61 e0 ldi r22, 0x01 ; 1
+ 2d6: 70 e0 ldi r23, 0x00 ; 0
+ 2d8: f7 d4 rcall .+2542 ; 0xcc8 <_Z20effect_random_fillerii>
+ effect_z_updown(20,1000);
+ 2da: 84 e1 ldi r24, 0x14 ; 20
+ 2dc: 90 e0 ldi r25, 0x00 ; 0
+ 2de: 68 ee ldi r22, 0xE8 ; 232
+ 2e0: 73 e0 ldi r23, 0x03 ; 3
+ 2e2: 47 d4 rcall .+2190 ; 0xb72 <_Z15effect_z_updownii>
+ effect_wormsqueeze (2, AXIS_Z, -1, 100, 1000);
+ 2e4: 82 e0 ldi r24, 0x02 ; 2
+ 2e6: 90 e0 ldi r25, 0x00 ; 0
+ 2e8: 6a e7 ldi r22, 0x7A ; 122
+ 2ea: 70 e0 ldi r23, 0x00 ; 0
+ 2ec: 4f ef ldi r20, 0xFF ; 255
+ 2ee: 5f ef ldi r21, 0xFF ; 255
+ 2f0: 24 e6 ldi r18, 0x64 ; 100
+ 2f2: 30 e0 ldi r19, 0x00 ; 0
+ 2f4: 08 ee ldi r16, 0xE8 ; 232
+ 2f6: 13 e0 ldi r17, 0x03 ; 3
+ 2f8: 9c d1 rcall .+824 ; 0x632 <_Z18effect_wormsqueezeiiiii>
+ effect_blinky2();
+ 2fa: b1 d5 rcall .+2914 ; 0xe5e <_Z14effect_blinky2v>
+ 2fc: 10 e0 ldi r17, 0x00 ; 0
+ // Comment the two lines above and uncomment this
+ // if you want the effects in a random order.
+ //launch_effect(rand()%EFFECTS_TOTAL);
+
+ for (char i = 0; i < 10; ++i) {
+ effect_boxside_randsend_parallel (AXIS_X, 0, 150, 1);
+ 2fe: 88 e7 ldi r24, 0x78 ; 120
+ 300: 60 e0 ldi r22, 0x00 ; 0
+ 302: 70 e0 ldi r23, 0x00 ; 0
+ 304: 46 e9 ldi r20, 0x96 ; 150
+ 306: 50 e0 ldi r21, 0x00 ; 0
+ 308: 21 e0 ldi r18, 0x01 ; 1
+ 30a: 30 e0 ldi r19, 0x00 ; 0
+ 30c: 5e d3 rcall .+1724 ; 0x9ca <_Z32effect_boxside_randsend_parallelciii>
+ effect_boxside_randsend_parallel (AXIS_X, 1, 150, 1);
+ 30e: 88 e7 ldi r24, 0x78 ; 120
+ 310: 61 e0 ldi r22, 0x01 ; 1
+ 312: 70 e0 ldi r23, 0x00 ; 0
+ 314: 46 e9 ldi r20, 0x96 ; 150
+ 316: 50 e0 ldi r21, 0x00 ; 0
+ 318: 21 e0 ldi r18, 0x01 ; 1
+ 31a: 30 e0 ldi r19, 0x00 ; 0
+ 31c: 56 d3 rcall .+1708 ; 0x9ca <_Z32effect_boxside_randsend_parallelciii>
+ effect_boxside_randsend_parallel (AXIS_Y, 0, 150, 1);
+ 31e: 89 e7 ldi r24, 0x79 ; 121
+ 320: 60 e0 ldi r22, 0x00 ; 0
+ 322: 70 e0 ldi r23, 0x00 ; 0
+ 324: 46 e9 ldi r20, 0x96 ; 150
+ 326: 50 e0 ldi r21, 0x00 ; 0
+ 328: 21 e0 ldi r18, 0x01 ; 1
+ 32a: 30 e0 ldi r19, 0x00 ; 0
+ 32c: 4e d3 rcall .+1692 ; 0x9ca <_Z32effect_boxside_randsend_parallelciii>
+ effect_boxside_randsend_parallel (AXIS_Y, 1, 150, 1);
+ 32e: 89 e7 ldi r24, 0x79 ; 121
+ 330: 61 e0 ldi r22, 0x01 ; 1
+ 332: 70 e0 ldi r23, 0x00 ; 0
+ 334: 46 e9 ldi r20, 0x96 ; 150
+ 336: 50 e0 ldi r21, 0x00 ; 0
+ 338: 21 e0 ldi r18, 0x01 ; 1
+ 33a: 30 e0 ldi r19, 0x00 ; 0
+ 33c: 46 d3 rcall .+1676 ; 0x9ca <_Z32effect_boxside_randsend_parallelciii>
+ effect_boxside_randsend_parallel (AXIS_Z, 0, 150, 1);
+ 33e: 8a e7 ldi r24, 0x7A ; 122
+ 340: 60 e0 ldi r22, 0x00 ; 0
+ 342: 70 e0 ldi r23, 0x00 ; 0
+ 344: 46 e9 ldi r20, 0x96 ; 150
+ 346: 50 e0 ldi r21, 0x00 ; 0
+ 348: 21 e0 ldi r18, 0x01 ; 1
+ 34a: 30 e0 ldi r19, 0x00 ; 0
+ 34c: 3e d3 rcall .+1660 ; 0x9ca <_Z32effect_boxside_randsend_parallelciii>
+ effect_boxside_randsend_parallel (AXIS_Z, 1, 150, 1);
+ 34e: 8a e7 ldi r24, 0x7A ; 122
+ 350: 61 e0 ldi r22, 0x01 ; 1
+ 352: 70 e0 ldi r23, 0x00 ; 0
+ 354: 46 e9 ldi r20, 0x96 ; 150
+ 356: 50 e0 ldi r21, 0x00 ; 0
+ 358: 21 e0 ldi r18, 0x01 ; 1
+ 35a: 30 e0 ldi r19, 0x00 ; 0
+ 35c: 36 d3 rcall .+1644 ; 0x9ca <_Z32effect_boxside_randsend_parallelciii>
+ // Show the effects in a random order.
+ // Comment the two lines above and uncomment this
+ // if you want the effects in a random order.
+ //launch_effect(rand()%EFFECTS_TOTAL);
+
+ for (char i = 0; i < 10; ++i) {
+ 35e: 1f 5f subi r17, 0xFF ; 255
+ 360: 1a 30 cpi r17, 0x0A ; 10
+ 362: 69 f6 brne .-102 ; 0x2fe <main+0xf2>
+ 364: 20 e0 ldi r18, 0x00 ; 0
+ 366: 77 cf rjmp .-274 ; 0x256 <main+0x4a>
+
+00000368 <_Z6myrandv>:
+// static short rand = 0;
+// rand=(rand*109+89)%251;
+// return rand;
+//}
+
+int myrand() { return rand(); }
+ 368: 75 d6 rcall .+3306 ; 0x1054 <rand>
+ 36a: 08 95 ret
+
+0000036c <_Z7inrangeiii>:
+}
+
+// This function validates that we are drawing inside the cube.
+unsigned char inrange(int x, int y, int z)
+{
+ if (x >= 0 && x < CUBE_SIZE && y >= 0 && y < CUBE_SIZE && z >= 0 && z < CUBE_SIZE)
+ 36c: 08 97 sbiw r24, 0x08 ; 8
+ 36e: 78 f4 brcc .+30 ; 0x38e <_Z7inrangeiii+0x22>
+ 370: 77 fd sbrc r23, 7
+ 372: 0d c0 rjmp .+26 ; 0x38e <_Z7inrangeiii+0x22>
+ 374: 68 30 cpi r22, 0x08 ; 8
+ 376: 71 05 cpc r23, r1
+ 378: 54 f4 brge .+20 ; 0x38e <_Z7inrangeiii+0x22>
+ 37a: 57 fd sbrc r21, 7
+ 37c: 08 c0 rjmp .+16 ; 0x38e <_Z7inrangeiii+0x22>
+ 37e: 90 e0 ldi r25, 0x00 ; 0
+ 380: 48 30 cpi r20, 0x08 ; 8
+ 382: 51 05 cpc r21, r1
+ 384: 0c f0 brlt .+2 ; 0x388 <_Z7inrangeiii+0x1c>
+ 386: 91 e0 ldi r25, 0x01 ; 1
+ 388: 81 e0 ldi r24, 0x01 ; 1
+ 38a: 98 27 eor r25, r24
+ 38c: 01 c0 rjmp .+2 ; 0x390 <_Z7inrangeiii+0x24>
+ 38e: 90 e0 ldi r25, 0x00 ; 0
+ } else
+ {
+ // One of the coordinates was outside the cube.
+ return 0;
+ }
+}
+ 390: 89 2f mov r24, r25
+ 392: 08 95 ret
+
+00000394 <_Z8clrvoxeliii>:
+ if (inrange(x,y,z))
+ fb[z][y] |= (1 << x);
+}
+
+// Set a single voxel to OFF
+void clrvoxel(int x, int y, int z)
+ 394: ff 92 push r15
+ 396: 0f 93 push r16
+ 398: 1f 93 push r17
+ 39a: cf 93 push r28
+ 39c: df 93 push r29
+ 39e: f8 2e mov r15, r24
+ 3a0: 8b 01 movw r16, r22
+ 3a2: ea 01 movw r28, r20
+{
+ if (inrange(x,y,z))
+ 3a4: e3 df rcall .-58 ; 0x36c <_Z7inrangeiii>
+ 3a6: 88 23 and r24, r24
+ 3a8: a9 f0 breq .+42 ; 0x3d4 <_Z8clrvoxeliii+0x40>
+ cube[z][y] &= ~(1 << x);
+ 3aa: fe 01 movw r30, r28
+ 3ac: 93 e0 ldi r25, 0x03 ; 3
+ 3ae: ee 0f add r30, r30
+ 3b0: ff 1f adc r31, r31
+ 3b2: 9a 95 dec r25
+ 3b4: e1 f7 brne .-8 ; 0x3ae <_Z8clrvoxeliii+0x1a>
+ 3b6: e0 0f add r30, r16
+ 3b8: f1 1f adc r31, r17
+ 3ba: ec 59 subi r30, 0x9C ; 156
+ 3bc: ff 4f sbci r31, 0xFF ; 255
+ 3be: 20 81 ld r18, Z
+ 3c0: 81 e0 ldi r24, 0x01 ; 1
+ 3c2: 90 e0 ldi r25, 0x00 ; 0
+ 3c4: 02 c0 rjmp .+4 ; 0x3ca <_Z8clrvoxeliii+0x36>
+ 3c6: 88 0f add r24, r24
+ 3c8: 99 1f adc r25, r25
+ 3ca: fa 94 dec r15
+ 3cc: e2 f7 brpl .-8 ; 0x3c6 <_Z8clrvoxeliii+0x32>
+ 3ce: 80 95 com r24
+ 3d0: 82 23 and r24, r18
+ 3d2: 80 83 st Z, r24
+}
+ 3d4: df 91 pop r29
+ 3d6: cf 91 pop r28
+ 3d8: 1f 91 pop r17
+ 3da: 0f 91 pop r16
+ 3dc: ff 90 pop r15
+ 3de: 08 95 ret
+
+000003e0 <_Z8setvoxeliii>:
+#include "draw.h"
+#include "string.h"
+
+// Set a single voxel to ON
+void setvoxel(int x, int y, int z)
+ 3e0: ff 92 push r15
+ 3e2: 0f 93 push r16
+ 3e4: 1f 93 push r17
+ 3e6: cf 93 push r28
+ 3e8: df 93 push r29
+ 3ea: f8 2e mov r15, r24
+ 3ec: 8b 01 movw r16, r22
+ 3ee: ea 01 movw r28, r20
+{
+ if (inrange(x,y,z))
+ 3f0: bd df rcall .-134 ; 0x36c <_Z7inrangeiii>
+ 3f2: 88 23 and r24, r24
+ 3f4: a1 f0 breq .+40 ; 0x41e <_Z8setvoxeliii+0x3e>
+ cube[z][y] |= (1 << x);
+ 3f6: fe 01 movw r30, r28
+ 3f8: 33 e0 ldi r19, 0x03 ; 3
+ 3fa: ee 0f add r30, r30
+ 3fc: ff 1f adc r31, r31
+ 3fe: 3a 95 dec r19
+ 400: e1 f7 brne .-8 ; 0x3fa <_Z8setvoxeliii+0x1a>
+ 402: e0 0f add r30, r16
+ 404: f1 1f adc r31, r17
+ 406: ec 59 subi r30, 0x9C ; 156
+ 408: ff 4f sbci r31, 0xFF ; 255
+ 40a: 20 81 ld r18, Z
+ 40c: 81 e0 ldi r24, 0x01 ; 1
+ 40e: 90 e0 ldi r25, 0x00 ; 0
+ 410: 02 c0 rjmp .+4 ; 0x416 <_Z8setvoxeliii+0x36>
+ 412: 88 0f add r24, r24
+ 414: 99 1f adc r25, r25
+ 416: fa 94 dec r15
+ 418: e2 f7 brpl .-8 ; 0x412 <_Z8setvoxeliii+0x32>
+ 41a: 28 2b or r18, r24
+ 41c: 20 83 st Z, r18
+}
+ 41e: df 91 pop r29
+ 420: cf 91 pop r28
+ 422: 1f 91 pop r17
+ 424: 0f 91 pop r16
+ 426: ff 90 pop r15
+ 428: 08 95 ret
+
+0000042a <_Z8getvoxeliii>:
+ return 0;
+ }
+}
+
+// Get the current status of a voxel
+unsigned char getvoxel(int x, int y, int z)
+ 42a: ff 92 push r15
+ 42c: 0f 93 push r16
+ 42e: 1f 93 push r17
+ 430: cf 93 push r28
+ 432: df 93 push r29
+ 434: f8 2e mov r15, r24
+ 436: 8b 01 movw r16, r22
+ 438: ea 01 movw r28, r20
+{
+ if (inrange(x,y,z))
+ 43a: 98 df rcall .-208 ; 0x36c <_Z7inrangeiii>
+ 43c: 88 23 and r24, r24
+ 43e: 89 f0 breq .+34 ; 0x462 <__stack+0x3>
+ {
+ if (cube[z][y] & (1 << x))
+ 440: 43 e0 ldi r20, 0x03 ; 3
+ 442: cc 0f add r28, r28
+ 444: dd 1f adc r29, r29
+ 446: 4a 95 dec r20
+ 448: e1 f7 brne .-8 ; 0x442 <_Z8getvoxeliii+0x18>
+ 44a: c0 0f add r28, r16
+ 44c: d1 1f adc r29, r17
+ 44e: cc 59 subi r28, 0x9C ; 156
+ 450: df 4f sbci r29, 0xFF ; 255
+ 452: 88 81 ld r24, Y
+ 454: 90 e0 ldi r25, 0x00 ; 0
+ 456: 02 c0 rjmp .+4 ; 0x45c <_Z8getvoxeliii+0x32>
+ 458: 95 95 asr r25
+ 45a: 87 95 ror r24
+ 45c: fa 94 dec r15
+ 45e: e2 f7 brpl .-8 ; 0x458 <_Z8getvoxeliii+0x2e>
+ 460: 81 70 andi r24, 0x01 ; 1
+ }
+ } else
+ {
+ return 0;
+ }
+}
+ 462: df 91 pop r29
+ 464: cf 91 pop r28
+ 466: 1f 91 pop r17
+ 468: 0f 91 pop r16
+ 46a: ff 90 pop r15
+ 46c: 08 95 ret
+
+0000046e <_Z10altervoxeliiii>:
+
+// In some effect we want to just take bool and write it to a voxel
+// this function calls the apropriate voxel manipulation function.
+void altervoxel(int x, int y, int z, int state)
+{
+ if (state == 1)
+ 46e: 21 30 cpi r18, 0x01 ; 1
+ 470: 31 05 cpc r19, r1
+ 472: 11 f4 brne .+4 ; 0x478 <_Z10altervoxeliiii+0xa>
+ {
+ setvoxel(x,y,z);
+ 474: b5 df rcall .-150 ; 0x3e0 <_Z8setvoxeliii>
+ 476: 08 95 ret
+ } else
+ {
+ clrvoxel(x,y,z);
+ 478: 8d df rcall .-230 ; 0x394 <_Z8clrvoxeliii>
+ 47a: 08 95 ret
+
+0000047c <_Z4fillh>:
+}
+
+// Fill a value into all 64 byts of the cube buffer
+// Mostly used for clearing. fill(0x00)
+// or setting all on. fill(0xff)
+void fill (unsigned char pattern)
+ 47c: 40 e0 ldi r20, 0x00 ; 0
+ 47e: 50 e0 ldi r21, 0x00 ; 0
+ 480: 10 c0 rjmp .+32 ; 0x4a2 <_Z4fillh+0x26>
+ int y;
+ for (z=0;z<CUBE_SIZE;z++)
+ {
+ for (y=0;y<CUBE_SIZE;y++)
+ {
+ cube[z][y] = pattern;
+ 482: fb 01 movw r30, r22
+ 484: e2 0f add r30, r18
+ 486: f3 1f adc r31, r19
+ 488: ec 59 subi r30, 0x9C ; 156
+ 48a: ff 4f sbci r31, 0xFF ; 255
+ 48c: 80 83 st Z, r24
+{
+ int z;
+ int y;
+ for (z=0;z<CUBE_SIZE;z++)
+ {
+ for (y=0;y<CUBE_SIZE;y++)
+ 48e: 2f 5f subi r18, 0xFF ; 255
+ 490: 3f 4f sbci r19, 0xFF ; 255
+ 492: 28 30 cpi r18, 0x08 ; 8
+ 494: 31 05 cpc r19, r1
+ 496: a9 f7 brne .-22 ; 0x482 <_Z4fillh+0x6>
+// or setting all on. fill(0xff)
+void fill (unsigned char pattern)
+{
+ int z;
+ int y;
+ for (z=0;z<CUBE_SIZE;z++)
+ 498: 4f 5f subi r20, 0xFF ; 255
+ 49a: 5f 4f sbci r21, 0xFF ; 255
+ 49c: 48 30 cpi r20, 0x08 ; 8
+ 49e: 51 05 cpc r21, r1
+ 4a0: 49 f0 breq .+18 ; 0x4b4 <_Z4fillh+0x38>
+ 4a2: 20 e0 ldi r18, 0x00 ; 0
+ 4a4: 30 e0 ldi r19, 0x00 ; 0
+ {
+ for (y=0;y<CUBE_SIZE;y++)
+ {
+ cube[z][y] = pattern;
+ 4a6: ba 01 movw r22, r20
+ 4a8: e3 e0 ldi r30, 0x03 ; 3
+ 4aa: 66 0f add r22, r22
+ 4ac: 77 1f adc r23, r23
+ 4ae: ea 95 dec r30
+ 4b0: e1 f7 brne .-8 ; 0x4aa <_Z4fillh+0x2e>
+ 4b2: e7 cf rjmp .-50 ; 0x482 <_Z4fillh+0x6>
+ 4b4: 08 95 ret
+
+000004b6 <_Z8delay_msj>:
+// Delay loop.
+// This is not calibrated to milliseconds,
+// but we had allready made to many effects using this
+// calibration when we figured it might be a good idea
+// to calibrate it.
+void delay_ms(uint16_t x)
+ 4b6: 0b c0 rjmp .+22 ; 0x4ce <_Z8delay_msj+0x18>
+{
+ uint8_t y, z;
+ for ( ; x > 0 ; x--){
+ 4b8: 20 e0 ldi r18, 0x00 ; 0
+ ...
+ for ( y = 0 ; y < 90 ; y++){
+ 4c6: 2f 5f subi r18, 0xFF ; 255
+ 4c8: 2a 35 cpi r18, 0x5A ; 90
+ 4ca: b9 f7 brne .-18 ; 0x4ba <_Z8delay_msj+0x4>
+// calibration when we figured it might be a good idea
+// to calibrate it.
+void delay_ms(uint16_t x)
+{
+ uint8_t y, z;
+ for ( ; x > 0 ; x--){
+ 4cc: 01 97 sbiw r24, 0x01 ; 1
+ 4ce: 00 97 sbiw r24, 0x00 ; 0
+ 4d0: 99 f7 brne .-26 ; 0x4b8 <_Z8delay_msj+0x2>
+ for ( z = 0 ; z < 6 ; z++){
+ asm volatile ("nop");
+ }
+ }
+ }
+}
+ 4d2: 08 95 ret
+
+000004d4 <_Z5shiftci>:
+
+// Shift the entire contents of the cube along an axis
+// This is great for effects where you want to draw something
+// on one side of the cube and have it flow towards the other
+// side. Like rain flowing down the Z axiz.
+void shift (char axis, int direction)
+ 4d4: 2f 92 push r2
+ 4d6: 3f 92 push r3
+ 4d8: 4f 92 push r4
+ 4da: 5f 92 push r5
+ 4dc: 6f 92 push r6
+ 4de: 7f 92 push r7
+ 4e0: 9f 92 push r9
+ 4e2: af 92 push r10
+ 4e4: bf 92 push r11
+ 4e6: cf 92 push r12
+ 4e8: df 92 push r13
+ 4ea: ef 92 push r14
+ 4ec: ff 92 push r15
+ 4ee: 0f 93 push r16
+ 4f0: 1f 93 push r17
+ 4f2: cf 93 push r28
+ 4f4: df 93 push r29
+ 4f6: 98 2e mov r9, r24
+ 4f8: 5b 01 movw r10, r22
+ 4fa: cc 24 eor r12, r12
+ 4fc: dd 24 eor r13, r13
+ int ii, iii;
+ int state;
+
+ for (i = 0; i < CUBE_SIZE; i++)
+ {
+ if (direction == -1)
+ 4fe: 47 e0 ldi r20, 0x07 ; 7
+ 500: 24 2e mov r2, r20
+ 502: 31 2c mov r3, r1
+ 504: 8f ef ldi r24, 0xFF ; 255
+ 506: a8 16 cp r10, r24
+ 508: 8f ef ldi r24, 0xFF ; 255
+ 50a: b8 06 cpc r11, r24
+ 50c: 11 f4 brne .+4 ; 0x512 <_Z5shiftci+0x3e>
+ 50e: 76 01 movw r14, r12
+ 510: 03 c0 rjmp .+6 ; 0x518 <_Z5shiftci+0x44>
+ 512: 71 01 movw r14, r2
+ 514: ec 18 sub r14, r12
+ 516: fd 08 sbc r15, r13
+ 518: 00 e0 ldi r16, 0x00 ; 0
+ 51a: 10 e0 ldi r17, 0x00 ; 0
+ if (direction == -1)
+ {
+ iii = ii+1;
+ } else
+ {
+ iii = ii-1;
+ 51c: 27 01 movw r4, r14
+ 51e: 08 94 sec
+ 520: 41 08 sbc r4, r1
+ 522: 51 08 sbc r5, r1
+ {
+ for (y = 0; y < CUBE_SIZE; y++)
+ {
+ if (direction == -1)
+ {
+ iii = ii+1;
+ 524: 37 01 movw r6, r14
+ 526: 08 94 sec
+ 528: 61 1c adc r6, r1
+ 52a: 71 1c adc r7, r1
+ 52c: 36 c0 rjmp .+108 ; 0x59a <_Z5shiftci+0xc6>
+
+ for (x = 0; x < CUBE_SIZE; x++)
+ {
+ for (y = 0; y < CUBE_SIZE; y++)
+ {
+ if (direction == -1)
+ 52e: 8f ef ldi r24, 0xFF ; 255
+ 530: a8 16 cp r10, r24
+ 532: 8f ef ldi r24, 0xFF ; 255
+ 534: b8 06 cpc r11, r24
+ 536: 11 f4 brne .+4 ; 0x53c <_Z5shiftci+0x68>
+ {
+ iii = ii+1;
+ 538: c3 01 movw r24, r6
+ 53a: 01 c0 rjmp .+2 ; 0x53e <_Z5shiftci+0x6a>
+ } else
+ {
+ iii = ii-1;
+ 53c: c2 01 movw r24, r4
+ 53e: ac 01 movw r20, r24
+ }
+
+ if (axis == AXIS_Z)
+ 540: 8a e7 ldi r24, 0x7A ; 122
+ 542: 98 16 cp r9, r24
+ 544: 41 f4 brne .+16 ; 0x556 <_Z5shiftci+0x82>
+ {
+ state = getvoxel(x,y,iii);
+ 546: c8 01 movw r24, r16
+ 548: be 01 movw r22, r28
+ 54a: 6f df rcall .-290 ; 0x42a <_Z8getvoxeliii>
+ 54c: 28 2f mov r18, r24
+ altervoxel(x,y,ii,state);
+ 54e: c8 01 movw r24, r16
+ 550: be 01 movw r22, r28
+ 552: a7 01 movw r20, r14
+ 554: 17 c0 rjmp .+46 ; 0x584 <_Z5shiftci+0xb0>
+ }
+
+ if (axis == AXIS_Y)
+ 556: 89 e7 ldi r24, 0x79 ; 121
+ 558: 98 16 cp r9, r24
+ 55a: 49 f4 brne .+18 ; 0x56e <_Z5shiftci+0x9a>
+ {
+ state = getvoxel(x,iii,y);
+ 55c: c8 01 movw r24, r16
+ 55e: ba 01 movw r22, r20
+ 560: ae 01 movw r20, r28
+ 562: 63 df rcall .-314 ; 0x42a <_Z8getvoxeliii>
+ 564: 28 2f mov r18, r24
+ altervoxel(x,ii,y,state);
+ 566: c8 01 movw r24, r16
+ 568: b7 01 movw r22, r14
+ 56a: ae 01 movw r20, r28
+ 56c: 0b c0 rjmp .+22 ; 0x584 <_Z5shiftci+0xb0>
+ }
+
+ if (axis == AXIS_X)
+ 56e: 88 e7 ldi r24, 0x78 ; 120
+ 570: 98 16 cp r9, r24
+ 572: 51 f4 brne .+20 ; 0x588 <_Z5shiftci+0xb4>
+ {
+ state = getvoxel(iii,y,x);
+ 574: ca 01 movw r24, r20
+ 576: be 01 movw r22, r28
+ 578: a8 01 movw r20, r16
+ 57a: 57 df rcall .-338 ; 0x42a <_Z8getvoxeliii>
+ 57c: 28 2f mov r18, r24
+ altervoxel(ii,y,x,state);
+ 57e: c7 01 movw r24, r14
+ 580: be 01 movw r22, r28
+ 582: a8 01 movw r20, r16
+ 584: 30 e0 ldi r19, 0x00 ; 0
+ 586: 73 df rcall .-282 ; 0x46e <_Z10altervoxeliiii>
+ }
+
+
+ for (x = 0; x < CUBE_SIZE; x++)
+ {
+ for (y = 0; y < CUBE_SIZE; y++)
+ 588: 21 96 adiw r28, 0x01 ; 1
+ 58a: c8 30 cpi r28, 0x08 ; 8
+ 58c: d1 05 cpc r29, r1
+ 58e: 79 f6 brne .-98 ; 0x52e <_Z5shiftci+0x5a>
+ {
+ ii = (7-i);
+ }
+
+
+ for (x = 0; x < CUBE_SIZE; x++)
+ 590: 0f 5f subi r16, 0xFF ; 255
+ 592: 1f 4f sbci r17, 0xFF ; 255
+ 594: 08 30 cpi r16, 0x08 ; 8
+ 596: 11 05 cpc r17, r1
+ 598: 19 f0 breq .+6 ; 0x5a0 <_Z5shiftci+0xcc>
+ 59a: c0 e0 ldi r28, 0x00 ; 0
+ 59c: d0 e0 ldi r29, 0x00 ; 0
+ 59e: c7 cf rjmp .-114 ; 0x52e <_Z5shiftci+0x5a>
+{
+ int i, x ,y;
+ int ii, iii;
+ int state;
+
+ for (i = 0; i < CUBE_SIZE; i++)
+ 5a0: 08 94 sec
+ 5a2: c1 1c adc r12, r1
+ 5a4: d1 1c adc r13, r1
+ 5a6: 88 e0 ldi r24, 0x08 ; 8
+ 5a8: c8 16 cp r12, r24
+ 5aa: d1 04 cpc r13, r1
+ 5ac: 09 f0 breq .+2 ; 0x5b0 <_Z5shiftci+0xdc>
+ 5ae: aa cf rjmp .-172 ; 0x504 <_Z5shiftci+0x30>
+ }
+ }
+ }
+ }
+
+ if (direction == -1)
+ 5b0: 8f ef ldi r24, 0xFF ; 255
+ 5b2: a8 16 cp r10, r24
+ 5b4: 8f ef ldi r24, 0xFF ; 255
+ 5b6: b8 06 cpc r11, r24
+ 5b8: 19 f0 breq .+6 ; 0x5c0 <_Z5shiftci+0xec>
+ 5ba: ee 24 eor r14, r14
+ 5bc: ff 24 eor r15, r15
+ 5be: 03 c0 rjmp .+6 ; 0x5c6 <_Z5shiftci+0xf2>
+ 5c0: 37 e0 ldi r19, 0x07 ; 7
+ 5c2: e3 2e mov r14, r19
+ 5c4: f1 2c mov r15, r1
+ 5c6: 00 e0 ldi r16, 0x00 ; 0
+ 5c8: 10 e0 ldi r17, 0x00 ; 0
+ 5ca: 1e c0 rjmp .+60 ; 0x608 <_Z5shiftci+0x134>
+
+ for (x = 0; x < CUBE_SIZE; x++)
+ {
+ for (y = 0; y < CUBE_SIZE; y++)
+ {
+ if (axis == AXIS_Z)
+ 5cc: 8a e7 ldi r24, 0x7A ; 122
+ 5ce: 98 16 cp r9, r24
+ 5d0: 21 f4 brne .+8 ; 0x5da <_Z5shiftci+0x106>
+ clrvoxel(x,y,i);
+ 5d2: c8 01 movw r24, r16
+ 5d4: be 01 movw r22, r28
+ 5d6: a7 01 movw r20, r14
+ 5d8: 0d c0 rjmp .+26 ; 0x5f4 <_Z5shiftci+0x120>
+
+ if (axis == AXIS_Y)
+ 5da: 89 e7 ldi r24, 0x79 ; 121
+ 5dc: 98 16 cp r9, r24
+ 5de: 21 f4 brne .+8 ; 0x5e8 <_Z5shiftci+0x114>
+ clrvoxel(x,i,y);
+ 5e0: c8 01 movw r24, r16
+ 5e2: b7 01 movw r22, r14
+ 5e4: ae 01 movw r20, r28
+ 5e6: 06 c0 rjmp .+12 ; 0x5f4 <_Z5shiftci+0x120>
+
+ if (axis == AXIS_X)
+ 5e8: 88 e7 ldi r24, 0x78 ; 120
+ 5ea: 98 16 cp r9, r24
+ 5ec: 21 f4 brne .+8 ; 0x5f6 <_Z5shiftci+0x122>
+ clrvoxel(i,y,x);
+ 5ee: c7 01 movw r24, r14
+ 5f0: be 01 movw r22, r28
+ 5f2: a8 01 movw r20, r16
+ 5f4: cf de rcall .-610 ; 0x394 <_Z8clrvoxeliii>
+ i = 0;
+ }
+
+ for (x = 0; x < CUBE_SIZE; x++)
+ {
+ for (y = 0; y < CUBE_SIZE; y++)
+ 5f6: 21 96 adiw r28, 0x01 ; 1
+ 5f8: c8 30 cpi r28, 0x08 ; 8
+ 5fa: d1 05 cpc r29, r1
+ 5fc: 39 f7 brne .-50 ; 0x5cc <_Z5shiftci+0xf8>
+ } else
+ {
+ i = 0;
+ }
+
+ for (x = 0; x < CUBE_SIZE; x++)
+ 5fe: 0f 5f subi r16, 0xFF ; 255
+ 600: 1f 4f sbci r17, 0xFF ; 255
+ 602: 08 30 cpi r16, 0x08 ; 8
+ 604: 11 05 cpc r17, r1
+ 606: 19 f0 breq .+6 ; 0x60e <_Z5shiftci+0x13a>
+ 608: c0 e0 ldi r28, 0x00 ; 0
+ 60a: d0 e0 ldi r29, 0x00 ; 0
+ 60c: df cf rjmp .-66 ; 0x5cc <_Z5shiftci+0xf8>
+
+ if (axis == AXIS_X)
+ clrvoxel(i,y,x);
+ }
+ }
+}
+ 60e: df 91 pop r29
+ 610: cf 91 pop r28
+ 612: 1f 91 pop r17
+ 614: 0f 91 pop r16
+ 616: ff 90 pop r15
+ 618: ef 90 pop r14
+ 61a: df 90 pop r13
+ 61c: cf 90 pop r12
+ 61e: bf 90 pop r11
+ 620: af 90 pop r10
+ 622: 9f 90 pop r9
+ 624: 7f 90 pop r7
+ 626: 6f 90 pop r6
+ 628: 5f 90 pop r5
+ 62a: 4f 90 pop r4
+ 62c: 3f 90 pop r3
+ 62e: 2f 90 pop r2
+ 630: 08 95 ret
+
+00000632 <_Z18effect_wormsqueezeiiiii>:
+ x = effect_telcstairs_do(x,val,delay);
+ }
+ }
+}
+
+void effect_wormsqueeze (int size, int axis, int direction, int iterations, int delay)
+ 632: 2f 92 push r2
+ 634: 3f 92 push r3
+ 636: 4f 92 push r4
+ 638: 5f 92 push r5
+ 63a: 6f 92 push r6
+ 63c: 7f 92 push r7
+ 63e: 8f 92 push r8
+ 640: 9f 92 push r9
+ 642: af 92 push r10
+ 644: bf 92 push r11
+ 646: cf 92 push r12
+ 648: df 92 push r13
+ 64a: ef 92 push r14
+ 64c: ff 92 push r15
+ 64e: 0f 93 push r16
+ 650: 1f 93 push r17
+ 652: df 93 push r29
+ 654: cf 93 push r28
+ 656: cd b7 in r28, 0x3d ; 61
+ 658: de b7 in r29, 0x3e ; 62
+ 65a: 2e 97 sbiw r28, 0x0e ; 14
+ 65c: 0f b6 in r0, 0x3f ; 63
+ 65e: f8 94 cli
+ 660: de bf out 0x3e, r29 ; 62
+ 662: 0f be out 0x3f, r0 ; 63
+ 664: cd bf out 0x3d, r28 ; 61
+ 666: 9a 83 std Y+2, r25 ; 0x02
+ 668: 89 83 std Y+1, r24 ; 0x01
+ 66a: 7c 83 std Y+4, r23 ; 0x04
+ 66c: 6b 83 std Y+3, r22 ; 0x03
+ 66e: 5e 83 std Y+6, r21 ; 0x06
+ 670: 4d 83 std Y+5, r20 ; 0x05
+ 672: 38 87 std Y+8, r19 ; 0x08
+ 674: 2f 83 std Y+7, r18 ; 0x07
+ 676: 1a 87 std Y+10, r17 ; 0x0a
+ 678: 09 87 std Y+9, r16 ; 0x09
+{
+ int x, y, i,j,k, dx, dy;
+ int cube_size;
+ int origin = 0;
+
+ if (direction == -1)
+ 67a: 4f 5f subi r20, 0xFF ; 255
+ 67c: 5f 4f sbci r21, 0xFF ; 255
+ 67e: 21 f4 brne .+8 ; 0x688 <_Z18effect_wormsqueezeiiiii+0x56>
+ 680: 97 e0 ldi r25, 0x07 ; 7
+ 682: 29 2e mov r2, r25
+ 684: 31 2c mov r3, r1
+ 686: 02 c0 rjmp .+4 ; 0x68c <_Z18effect_wormsqueezeiiiii+0x5a>
+ 688: 22 24 eor r2, r2
+ 68a: 33 24 eor r3, r3
+ origin = 7;
+
+ cube_size = 8-(size-1);
+ 68c: 89 e0 ldi r24, 0x09 ; 9
+ 68e: 68 2e mov r6, r24
+ 690: 71 2c mov r7, r1
+ 692: 89 81 ldd r24, Y+1 ; 0x01
+ 694: 9a 81 ldd r25, Y+2 ; 0x02
+ 696: 68 1a sub r6, r24
+ 698: 79 0a sbc r7, r25
+
+ x = myrand()%cube_size;
+ 69a: 66 de rcall .-820 ; 0x368 <_Z6myrandv>
+ 69c: b3 01 movw r22, r6
+ 69e: 32 d4 rcall .+2148 ; 0xf04 <__divmodhi4>
+ 6a0: 6c 01 movw r12, r24
+ y = myrand()%cube_size;
+ 6a2: 62 de rcall .-828 ; 0x368 <_Z6myrandv>
+ 6a4: b3 01 movw r22, r6
+ 6a6: 2e d4 rcall .+2140 ; 0xf04 <__divmodhi4>
+ 6a8: 7c 01 movw r14, r24
+ 6aa: 44 24 eor r4, r4
+ 6ac: 55 24 eor r5, r5
+ 6ae: 75 c0 rjmp .+234 ; 0x79a <_Z18effect_wormsqueezeiiiii+0x168>
+
+ for (i=0; i<iterations; i++)
+ {
+ dx = ((myrand()%3)-1);
+ 6b0: 5b de rcall .-842 ; 0x368 <_Z6myrandv>
+ 6b2: 8c 01 movw r16, r24
+ dy = ((myrand()%3)-1);
+ 6b4: 59 de rcall .-846 ; 0x368 <_Z6myrandv>
+ 6b6: 9c 01 movw r18, r24
+
+ if ((x+dx) > 0 && (x+dx) < cube_size)
+ 6b8: c8 01 movw r24, r16
+ 6ba: 63 e0 ldi r22, 0x03 ; 3
+ 6bc: 70 e0 ldi r23, 0x00 ; 0
+ 6be: 22 d4 rcall .+2116 ; 0xf04 <__divmodhi4>
+ 6c0: 01 97 sbiw r24, 0x01 ; 1
+ 6c2: 8c 0d add r24, r12
+ 6c4: 9d 1d adc r25, r13
+ 6c6: 9e 87 std Y+14, r25 ; 0x0e
+ 6c8: 8d 87 std Y+13, r24 ; 0x0d
+ 6ca: 18 16 cp r1, r24
+ 6cc: 19 06 cpc r1, r25
+ 6ce: 1c f4 brge .+6 ; 0x6d6 <_Z18effect_wormsqueezeiiiii+0xa4>
+ 6d0: 86 15 cp r24, r6
+ 6d2: 97 05 cpc r25, r7
+ 6d4: 14 f0 brlt .+4 ; 0x6da <_Z18effect_wormsqueezeiiiii+0xa8>
+ 6d6: de 86 std Y+14, r13 ; 0x0e
+ 6d8: cd 86 std Y+13, r12 ; 0x0d
+ x += dx;
+
+ if ((y+dy) > 0 && (y+dy) < cube_size)
+ 6da: c9 01 movw r24, r18
+ 6dc: 63 e0 ldi r22, 0x03 ; 3
+ 6de: 70 e0 ldi r23, 0x00 ; 0
+ 6e0: 11 d4 rcall .+2082 ; 0xf04 <__divmodhi4>
+ 6e2: 8c 01 movw r16, r24
+ 6e4: 01 50 subi r16, 0x01 ; 1
+ 6e6: 10 40 sbci r17, 0x00 ; 0
+ 6e8: 0e 0d add r16, r14
+ 6ea: 1f 1d adc r17, r15
+ 6ec: 10 16 cp r1, r16
+ 6ee: 11 06 cpc r1, r17
+ 6f0: 1c f4 brge .+6 ; 0x6f8 <_Z18effect_wormsqueezeiiiii+0xc6>
+ 6f2: 06 15 cp r16, r6
+ 6f4: 17 05 cpc r17, r7
+ 6f6: 0c f0 brlt .+2 ; 0x6fa <_Z18effect_wormsqueezeiiiii+0xc8>
+ 6f8: 87 01 movw r16, r14
+ y += dy;
+
+ shift(axis, direction);
+ 6fa: 8b 81 ldd r24, Y+3 ; 0x03
+ 6fc: 6d 81 ldd r22, Y+5 ; 0x05
+ 6fe: 7e 81 ldd r23, Y+6 ; 0x06
+ 700: e9 de rcall .-558 ; 0x4d4 <_Z5shiftci>
+ 702: 8d 84 ldd r8, Y+13 ; 0x0d
+ 704: 9e 84 ldd r9, Y+14 ; 0x0e
+ 706: aa 24 eor r10, r10
+ 708: bb 24 eor r11, r11
+ 70a: 30 c0 rjmp .+96 ; 0x76c <_Z18effect_wormsqueezeiiiii+0x13a>
+
+ for (j=0; j<size;j++)
+ {
+ for (k=0; k<size;k++)
+ {
+ if (axis == AXIS_Z)
+ 70c: eb 81 ldd r30, Y+3 ; 0x03
+ 70e: fc 81 ldd r31, Y+4 ; 0x04
+ 710: ea 37 cpi r30, 0x7A ; 122
+ 712: f1 05 cpc r31, r1
+ 714: 21 f4 brne .+8 ; 0x71e <_Z18effect_wormsqueezeiiiii+0xec>
+ setvoxel(x+j,y+k,origin);
+ 716: c4 01 movw r24, r8
+ 718: b6 01 movw r22, r12
+ 71a: a1 01 movw r20, r2
+ 71c: 15 c0 rjmp .+42 ; 0x748 <_Z18effect_wormsqueezeiiiii+0x116>
+
+ if (axis == AXIS_Y)
+ 71e: 8b 81 ldd r24, Y+3 ; 0x03
+ 720: 9c 81 ldd r25, Y+4 ; 0x04
+ 722: 89 37 cpi r24, 0x79 ; 121
+ 724: 91 05 cpc r25, r1
+ 726: 21 f4 brne .+8 ; 0x730 <_Z18effect_wormsqueezeiiiii+0xfe>
+ setvoxel(x+j,origin,y+k);
+ 728: c4 01 movw r24, r8
+ 72a: b1 01 movw r22, r2
+ 72c: a6 01 movw r20, r12
+ 72e: 0c c0 rjmp .+24 ; 0x748 <_Z18effect_wormsqueezeiiiii+0x116>
+
+ if (axis == AXIS_X)
+ 730: eb 81 ldd r30, Y+3 ; 0x03
+ 732: fc 81 ldd r31, Y+4 ; 0x04
+ 734: e8 37 cpi r30, 0x78 ; 120
+ 736: f1 05 cpc r31, r1
+ 738: 41 f4 brne .+16 ; 0x74a <_Z18effect_wormsqueezeiiiii+0x118>
+ setvoxel(origin,y+j,x+k);
+ 73a: 4d 85 ldd r20, Y+13 ; 0x0d
+ 73c: 5e 85 ldd r21, Y+14 ; 0x0e
+ 73e: 4e 0d add r20, r14
+ 740: 5f 1d adc r21, r15
+ 742: c1 01 movw r24, r2
+ 744: 6b 85 ldd r22, Y+11 ; 0x0b
+ 746: 7c 85 ldd r23, Y+12 ; 0x0c
+ 748: 4b de rcall .-874 ; 0x3e0 <_Z8setvoxeliii>
+ shift(axis, direction);
+
+
+ for (j=0; j<size;j++)
+ {
+ for (k=0; k<size;k++)
+ 74a: 08 94 sec
+ 74c: e1 1c adc r14, r1
+ 74e: f1 1c adc r15, r1
+ 750: 08 94 sec
+ 752: c1 1c adc r12, r1
+ 754: d1 1c adc r13, r1
+ 756: 89 81 ldd r24, Y+1 ; 0x01
+ 758: 9a 81 ldd r25, Y+2 ; 0x02
+ 75a: e8 16 cp r14, r24
+ 75c: f9 06 cpc r15, r25
+ 75e: b4 f2 brlt .-84 ; 0x70c <_Z18effect_wormsqueezeiiiii+0xda>
+ y += dy;
+
+ shift(axis, direction);
+
+
+ for (j=0; j<size;j++)
+ 760: 08 94 sec
+ 762: a1 1c adc r10, r1
+ 764: b1 1c adc r11, r1
+ 766: 08 94 sec
+ 768: 81 1c adc r8, r1
+ 76a: 91 1c adc r9, r1
+ 76c: e9 81 ldd r30, Y+1 ; 0x01
+ 76e: fa 81 ldd r31, Y+2 ; 0x02
+ 770: ae 16 cp r10, r30
+ 772: bf 06 cpc r11, r31
+ 774: 4c f4 brge .+18 ; 0x788 <_Z18effect_wormsqueezeiiiii+0x156>
+ 776: 68 01 movw r12, r16
+ 778: ee 24 eor r14, r14
+ 77a: ff 24 eor r15, r15
+
+ if (axis == AXIS_Y)
+ setvoxel(x+j,origin,y+k);
+
+ if (axis == AXIS_X)
+ setvoxel(origin,y+j,x+k);
+ 77c: c5 01 movw r24, r10
+ 77e: 80 0f add r24, r16
+ 780: 91 1f adc r25, r17
+ 782: 9c 87 std Y+12, r25 ; 0x0c
+ 784: 8b 87 std Y+11, r24 ; 0x0b
+ 786: e7 cf rjmp .-50 ; 0x756 <_Z18effect_wormsqueezeiiiii+0x124>
+ }
+ }
+
+ delay_ms(delay);
+ 788: 89 85 ldd r24, Y+9 ; 0x09
+ 78a: 9a 85 ldd r25, Y+10 ; 0x0a
+ 78c: 94 de rcall .-728 ; 0x4b6 <_Z8delay_msj>
+ cube_size = 8-(size-1);
+
+ x = myrand()%cube_size;
+ y = myrand()%cube_size;
+
+ for (i=0; i<iterations; i++)
+ 78e: 08 94 sec
+ 790: 41 1c adc r4, r1
+ 792: 51 1c adc r5, r1
+ 794: cd 84 ldd r12, Y+13 ; 0x0d
+ 796: de 84 ldd r13, Y+14 ; 0x0e
+ 798: 78 01 movw r14, r16
+ 79a: ef 81 ldd r30, Y+7 ; 0x07
+ 79c: f8 85 ldd r31, Y+8 ; 0x08
+ 79e: 4e 16 cp r4, r30
+ 7a0: 5f 06 cpc r5, r31
+ 7a2: 0c f4 brge .+2 ; 0x7a6 <_Z18effect_wormsqueezeiiiii+0x174>
+ 7a4: 85 cf rjmp .-246 ; 0x6b0 <_Z18effect_wormsqueezeiiiii+0x7e>
+ }
+ }
+
+ delay_ms(delay);
+ }
+}
+ 7a6: 2e 96 adiw r28, 0x0e ; 14
+ 7a8: 0f b6 in r0, 0x3f ; 63
+ 7aa: f8 94 cli
+ 7ac: de bf out 0x3e, r29 ; 62
+ 7ae: 0f be out 0x3f, r0 ; 63
+ 7b0: cd bf out 0x3d, r28 ; 61
+ 7b2: cf 91 pop r28
+ 7b4: df 91 pop r29
+ 7b6: 1f 91 pop r17
+ 7b8: 0f 91 pop r16
+ 7ba: ff 90 pop r15
+ 7bc: ef 90 pop r14
+ 7be: df 90 pop r13
+ 7c0: cf 90 pop r12
+ 7c2: bf 90 pop r11
+ 7c4: af 90 pop r10
+ 7c6: 9f 90 pop r9
+ 7c8: 8f 90 pop r8
+ 7ca: 7f 90 pop r7
+ 7cc: 6f 90 pop r6
+ 7ce: 5f 90 pop r5
+ 7d0: 4f 90 pop r4
+ 7d2: 3f 90 pop r3
+ 7d4: 2f 90 pop r2
+ 7d6: 08 95 ret
+
+000007d8 <_Z11effect_raini>:
+ }
+ }
+}
+
+
+void effect_rain (int iterations)
+ 7d8: af 92 push r10
+ 7da: bf 92 push r11
+ 7dc: cf 92 push r12
+ 7de: df 92 push r13
+ 7e0: ef 92 push r14
+ 7e2: ff 92 push r15
+ 7e4: 0f 93 push r16
+ 7e6: 1f 93 push r17
+ 7e8: cf 93 push r28
+ 7ea: df 93 push r29
+ 7ec: 5c 01 movw r10, r24
+ 7ee: cc 24 eor r12, r12
+ 7f0: dd 24 eor r13, r13
+ 7f2: 2a c0 rjmp .+84 ; 0x848 <_Z11effect_raini+0x70>
+ int rnd_y;
+ int rnd_num;
+
+ for (ii=0;ii<iterations;ii++)
+ {
+ rnd_num = myrand()%4;
+ 7f4: b9 dd rcall .-1166 ; 0x368 <_Z6myrandv>
+ 7f6: 64 e0 ldi r22, 0x04 ; 4
+ 7f8: 70 e0 ldi r23, 0x00 ; 0
+ 7fa: 84 d3 rcall .+1800 ; 0xf04 <__divmodhi4>
+ 7fc: ec 01 movw r28, r24
+ 7fe: ee 24 eor r14, r14
+ 800: ff 24 eor r15, r15
+ 802: 15 c0 rjmp .+42 ; 0x82e <_Z11effect_raini+0x56>
+
+ for (i=0; i < rnd_num;i++)
+ {
+ rnd_x = myrand()%8;
+ 804: b1 dd rcall .-1182 ; 0x368 <_Z6myrandv>
+ 806: 8c 01 movw r16, r24
+ rnd_y = myrand()%8;
+ 808: af dd rcall .-1186 ; 0x368 <_Z6myrandv>
+ 80a: 9c 01 movw r18, r24
+ setvoxel(rnd_x,rnd_y,7);
+ 80c: c8 01 movw r24, r16
+ 80e: 68 e0 ldi r22, 0x08 ; 8
+ 810: 70 e0 ldi r23, 0x00 ; 0
+ 812: 78 d3 rcall .+1776 ; 0xf04 <__divmodhi4>
+ 814: fc 01 movw r30, r24
+ 816: c9 01 movw r24, r18
+ 818: 68 e0 ldi r22, 0x08 ; 8
+ 81a: 70 e0 ldi r23, 0x00 ; 0
+ 81c: 73 d3 rcall .+1766 ; 0xf04 <__divmodhi4>
+ 81e: bc 01 movw r22, r24
+ 820: cf 01 movw r24, r30
+ 822: 47 e0 ldi r20, 0x07 ; 7
+ 824: 50 e0 ldi r21, 0x00 ; 0
+ 826: dc dd rcall .-1096 ; 0x3e0 <_Z8setvoxeliii>
+
+ for (ii=0;ii<iterations;ii++)
+ {
+ rnd_num = myrand()%4;
+
+ for (i=0; i < rnd_num;i++)
+ 828: 08 94 sec
+ 82a: e1 1c adc r14, r1
+ 82c: f1 1c adc r15, r1
+ 82e: ec 16 cp r14, r28
+ 830: fd 06 cpc r15, r29
+ 832: 44 f3 brlt .-48 ; 0x804 <_Z11effect_raini+0x2c>
+ rnd_x = myrand()%8;
+ rnd_y = myrand()%8;
+ setvoxel(rnd_x,rnd_y,7);
+ }
+
+ delay_ms(1000);
+ 834: 88 ee ldi r24, 0xE8 ; 232
+ 836: 93 e0 ldi r25, 0x03 ; 3
+ 838: 3e de rcall .-900 ; 0x4b6 <_Z8delay_msj>
+ shift(AXIS_Z,-1);
+ 83a: 8a e7 ldi r24, 0x7A ; 122
+ 83c: 6f ef ldi r22, 0xFF ; 255
+ 83e: 7f ef ldi r23, 0xFF ; 255
+ 840: 49 de rcall .-878 ; 0x4d4 <_Z5shiftci>
+ int i, ii;
+ int rnd_x;
+ int rnd_y;
+ int rnd_num;
+
+ for (ii=0;ii<iterations;ii++)
+ 842: 08 94 sec
+ 844: c1 1c adc r12, r1
+ 846: d1 1c adc r13, r1
+ 848: ca 14 cp r12, r10
+ 84a: db 04 cpc r13, r11
+ 84c: 9c f2 brlt .-90 ; 0x7f4 <_Z11effect_raini+0x1c>
+ }
+
+ delay_ms(1000);
+ shift(AXIS_Z,-1);
+ }
+}
+ 84e: df 91 pop r29
+ 850: cf 91 pop r28
+ 852: 1f 91 pop r17
+ 854: 0f 91 pop r16
+ 856: ff 90 pop r15
+ 858: ef 90 pop r14
+ 85a: df 90 pop r13
+ 85c: cf 90 pop r12
+ 85e: bf 90 pop r11
+ 860: af 90 pop r10
+ 862: 08 95 ret
+
+00000864 <_Z11sendvoxel_zhhhi>:
+}
+
+
+// Send a voxel flying from one side of the cube to the other
+// If its at the bottom, send it to the top..
+void sendvoxel_z (unsigned char x, unsigned char y, unsigned char z, int delay)
+ 864: 7f 92 push r7
+ 866: 8f 92 push r8
+ 868: 9f 92 push r9
+ 86a: af 92 push r10
+ 86c: bf 92 push r11
+ 86e: cf 92 push r12
+ 870: df 92 push r13
+ 872: ef 92 push r14
+ 874: ff 92 push r15
+ 876: 0f 93 push r16
+ 878: 1f 93 push r17
+ 87a: cf 93 push r28
+ 87c: df 93 push r29
+ 87e: e8 2e mov r14, r24
+ 880: f6 2e mov r15, r22
+ 882: 74 2e mov r7, r20
+ 884: 69 01 movw r12, r18
+ 886: c0 e0 ldi r28, 0x00 ; 0
+ 888: d0 e0 ldi r29, 0x00 ; 0
+ 88a: f7 e0 ldi r31, 0x07 ; 7
+ 88c: 8f 2e mov r8, r31
+ 88e: 91 2c mov r9, r1
+ for (i=0; i<8; i++)
+ {
+ if (z == 7)
+ {
+ ii = 7-i;
+ clrvoxel(x,y,ii+1);
+ 890: e8 e0 ldi r30, 0x08 ; 8
+ 892: ae 2e mov r10, r30
+ 894: b1 2c mov r11, r1
+void sendvoxel_z (unsigned char x, unsigned char y, unsigned char z, int delay)
+{
+ int i, ii;
+ for (i=0; i<8; i++)
+ {
+ if (z == 7)
+ 896: 87 e0 ldi r24, 0x07 ; 7
+ 898: 78 16 cp r7, r24
+ 89a: 61 f4 brne .+24 ; 0x8b4 <_Z11sendvoxel_zhhhi+0x50>
+}
+
+
+// Send a voxel flying from one side of the cube to the other
+// If its at the bottom, send it to the top..
+void sendvoxel_z (unsigned char x, unsigned char y, unsigned char z, int delay)
+ 89c: 84 01 movw r16, r8
+ 89e: 0c 1b sub r16, r28
+ 8a0: 1d 0b sbc r17, r29
+ for (i=0; i<8; i++)
+ {
+ if (z == 7)
+ {
+ ii = 7-i;
+ clrvoxel(x,y,ii+1);
+ 8a2: a5 01 movw r20, r10
+ 8a4: 4c 1b sub r20, r28
+ 8a6: 5d 0b sbc r21, r29
+ 8a8: 8e 2d mov r24, r14
+ 8aa: 90 e0 ldi r25, 0x00 ; 0
+ 8ac: 6f 2d mov r22, r15
+ 8ae: 70 e0 ldi r23, 0x00 ; 0
+ 8b0: 71 dd rcall .-1310 ; 0x394 <_Z8clrvoxeliii>
+ 8b2: 09 c0 rjmp .+18 ; 0x8c6 <_Z11sendvoxel_zhhhi+0x62>
+ } else
+ {
+ ii = i;
+ clrvoxel(x,y,ii-1);
+ 8b4: ae 01 movw r20, r28
+ 8b6: 41 50 subi r20, 0x01 ; 1
+ 8b8: 50 40 sbci r21, 0x00 ; 0
+ 8ba: 8e 2d mov r24, r14
+ 8bc: 90 e0 ldi r25, 0x00 ; 0
+ 8be: 6f 2d mov r22, r15
+ 8c0: 70 e0 ldi r23, 0x00 ; 0
+ 8c2: 68 dd rcall .-1328 ; 0x394 <_Z8clrvoxeliii>
+ 8c4: 8e 01 movw r16, r28
+ }
+ setvoxel(x,y,ii);
+ 8c6: 8e 2d mov r24, r14
+ 8c8: 90 e0 ldi r25, 0x00 ; 0
+ 8ca: 6f 2d mov r22, r15
+ 8cc: 70 e0 ldi r23, 0x00 ; 0
+ 8ce: a8 01 movw r20, r16
+ 8d0: 87 dd rcall .-1266 ; 0x3e0 <_Z8setvoxeliii>
+ delay_ms(delay);
+ 8d2: c6 01 movw r24, r12
+ 8d4: f0 dd rcall .-1056 ; 0x4b6 <_Z8delay_msj>
+// Send a voxel flying from one side of the cube to the other
+// If its at the bottom, send it to the top..
+void sendvoxel_z (unsigned char x, unsigned char y, unsigned char z, int delay)
+{
+ int i, ii;
+ for (i=0; i<8; i++)
+ 8d6: 21 96 adiw r28, 0x01 ; 1
+ 8d8: c8 30 cpi r28, 0x08 ; 8
+ 8da: d1 05 cpc r29, r1
+ 8dc: e1 f6 brne .-72 ; 0x896 <_Z11sendvoxel_zhhhi+0x32>
+ clrvoxel(x,y,ii-1);
+ }
+ setvoxel(x,y,ii);
+ delay_ms(delay);
+ }
+}
+ 8de: df 91 pop r29
+ 8e0: cf 91 pop r28
+ 8e2: 1f 91 pop r17
+ 8e4: 0f 91 pop r16
+ 8e6: ff 90 pop r15
+ 8e8: ef 90 pop r14
+ 8ea: df 90 pop r13
+ 8ec: cf 90 pop r12
+ 8ee: bf 90 pop r11
+ 8f0: af 90 pop r10
+ 8f2: 9f 90 pop r9
+ 8f4: 8f 90 pop r8
+ 8f6: 7f 90 pop r7
+ 8f8: 08 95 ret
+
+000008fa <_Z19draw_positions_axiscPhi>:
+ draw_positions_axis (axis, positions,invert);
+ delay_ms(delay);
+ }
+}
+
+void draw_positions_axis (char axis, unsigned char positions[64], int invert)
+ 8fa: 4f 92 push r4
+ 8fc: 5f 92 push r5
+ 8fe: 6f 92 push r6
+ 900: 7f 92 push r7
+ 902: 9f 92 push r9
+ 904: af 92 push r10
+ 906: bf 92 push r11
+ 908: cf 92 push r12
+ 90a: df 92 push r13
+ 90c: ef 92 push r14
+ 90e: ff 92 push r15
+ 910: 0f 93 push r16
+ 912: 1f 93 push r17
+ 914: cf 93 push r28
+ 916: df 93 push r29
+ 918: 98 2e mov r9, r24
+ 91a: 16 2f mov r17, r22
+ 91c: 07 2f mov r16, r23
+ 91e: 3a 01 movw r6, r20
+{
+ int x, y, p;
+
+ fill(0x00);
+ 920: 80 e0 ldi r24, 0x00 ; 0
+ 922: ac dd rcall .-1192 ; 0x47c <_Z4fillh>
+ 924: 21 2f mov r18, r17
+ 926: 30 2f mov r19, r16
+ 928: c9 01 movw r24, r18
+ 92a: 6c 01 movw r12, r24
+ 92c: c0 e0 ldi r28, 0x00 ; 0
+ 92e: d0 e0 ldi r29, 0x00 ; 0
+ {
+ for (y=0; y<8; y++)
+ {
+ if (invert)
+ {
+ p = (7-positions[(x*8)+y]);
+ 930: 57 e0 ldi r21, 0x07 ; 7
+ 932: 45 2e mov r4, r21
+ 934: 51 2c mov r5, r1
+ 936: 34 c0 rjmp .+104 ; 0x9a0 <_Z19draw_positions_axiscPhi+0xa6>
+
+ for (x=0; x<8; x++)
+ {
+ for (y=0; y<8; y++)
+ {
+ if (invert)
+ 938: 61 14 cp r6, r1
+ 93a: 71 04 cpc r7, r1
+ 93c: 31 f0 breq .+12 ; 0x94a <_Z19draw_positions_axiscPhi+0x50>
+ {
+ p = (7-positions[(x*8)+y]);
+ 93e: f5 01 movw r30, r10
+ 940: 80 81 ld r24, Z
+ 942: a2 01 movw r20, r4
+ 944: 48 1b sub r20, r24
+ 946: 51 09 sbc r21, r1
+ 948: 04 c0 rjmp .+8 ; 0x952 <_Z19draw_positions_axiscPhi+0x58>
+ } else
+ {
+ p = positions[(x*8)+y];
+ 94a: f7 01 movw r30, r14
+ 94c: 80 81 ld r24, Z
+ 94e: 48 2f mov r20, r24
+ 950: 50 e0 ldi r21, 0x00 ; 0
+ }
+
+ if (axis == AXIS_Z)
+ 952: fa e7 ldi r31, 0x7A ; 122
+ 954: 9f 16 cp r9, r31
+ 956: 19 f4 brne .+6 ; 0x95e <_Z19draw_positions_axiscPhi+0x64>
+ setvoxel(x,y,p);
+ 958: ce 01 movw r24, r28
+ 95a: b8 01 movw r22, r16
+ 95c: 0d c0 rjmp .+26 ; 0x978 <_Z19draw_positions_axiscPhi+0x7e>
+
+ if (axis == AXIS_Y)
+ 95e: 89 e7 ldi r24, 0x79 ; 121
+ 960: 98 16 cp r9, r24
+ 962: 21 f4 brne .+8 ; 0x96c <_Z19draw_positions_axiscPhi+0x72>
+ setvoxel(x,p,y);
+ 964: ce 01 movw r24, r28
+ 966: ba 01 movw r22, r20
+ 968: a8 01 movw r20, r16
+ 96a: 06 c0 rjmp .+12 ; 0x978 <_Z19draw_positions_axiscPhi+0x7e>
+
+ if (axis == AXIS_X)
+ 96c: 98 e7 ldi r25, 0x78 ; 120
+ 96e: 99 16 cp r9, r25
+ 970: 21 f4 brne .+8 ; 0x97a <_Z19draw_positions_axiscPhi+0x80>
+ setvoxel(p,y,x);
+ 972: ca 01 movw r24, r20
+ 974: b8 01 movw r22, r16
+ 976: ae 01 movw r20, r28
+ 978: 33 dd rcall .-1434 ; 0x3e0 <_Z8setvoxeliii>
+
+ fill(0x00);
+
+ for (x=0; x<8; x++)
+ {
+ for (y=0; y<8; y++)
+ 97a: 0f 5f subi r16, 0xFF ; 255
+ 97c: 1f 4f sbci r17, 0xFF ; 255
+ 97e: 08 94 sec
+ 980: a1 1c adc r10, r1
+ 982: b1 1c adc r11, r1
+ 984: 08 94 sec
+ 986: e1 1c adc r14, r1
+ 988: f1 1c adc r15, r1
+ 98a: 08 30 cpi r16, 0x08 ; 8
+ 98c: 11 05 cpc r17, r1
+ 98e: a1 f6 brne .-88 ; 0x938 <_Z19draw_positions_axiscPhi+0x3e>
+{
+ int x, y, p;
+
+ fill(0x00);
+
+ for (x=0; x<8; x++)
+ 990: 21 96 adiw r28, 0x01 ; 1
+ 992: e8 e0 ldi r30, 0x08 ; 8
+ 994: f0 e0 ldi r31, 0x00 ; 0
+ 996: ce 0e add r12, r30
+ 998: df 1e adc r13, r31
+ 99a: c8 30 cpi r28, 0x08 ; 8
+ 99c: d1 05 cpc r29, r1
+ 99e: 29 f0 breq .+10 ; 0x9aa <_Z19draw_positions_axiscPhi+0xb0>
+ 9a0: 56 01 movw r10, r12
+ 9a2: 76 01 movw r14, r12
+ 9a4: 00 e0 ldi r16, 0x00 ; 0
+ 9a6: 10 e0 ldi r17, 0x00 ; 0
+ 9a8: c7 cf rjmp .-114 ; 0x938 <_Z19draw_positions_axiscPhi+0x3e>
+ if (axis == AXIS_X)
+ setvoxel(p,y,x);
+ }
+ }
+
+}
+ 9aa: df 91 pop r29
+ 9ac: cf 91 pop r28
+ 9ae: 1f 91 pop r17
+ 9b0: 0f 91 pop r16
+ 9b2: ff 90 pop r15
+ 9b4: ef 90 pop r14
+ 9b6: df 90 pop r13
+ 9b8: cf 90 pop r12
+ 9ba: bf 90 pop r11
+ 9bc: af 90 pop r10
+ 9be: 9f 90 pop r9
+ 9c0: 7f 90 pop r7
+ 9c2: 6f 90 pop r6
+ 9c4: 5f 90 pop r5
+ 9c6: 4f 90 pop r4
+ 9c8: 08 95 ret
+
+000009ca <_Z32effect_boxside_randsend_parallelciii>:
+
+
+void effect_boxside_randsend_parallel (char axis, int origin, int delay, int mode)
+ 9ca: 2f 92 push r2
+ 9cc: 3f 92 push r3
+ 9ce: 4f 92 push r4
+ 9d0: 5f 92 push r5
+ 9d2: 6f 92 push r6
+ 9d4: 7f 92 push r7
+ 9d6: 8f 92 push r8
+ 9d8: 9f 92 push r9
+ 9da: af 92 push r10
+ 9dc: bf 92 push r11
+ 9de: cf 92 push r12
+ 9e0: df 92 push r13
+ 9e2: ef 92 push r14
+ 9e4: ff 92 push r15
+ 9e6: 0f 93 push r16
+ 9e8: 1f 93 push r17
+ 9ea: df 93 push r29
+ 9ec: cf 93 push r28
+ 9ee: cd b7 in r28, 0x3d ; 61
+ 9f0: de b7 in r29, 0x3e ; 62
+ 9f2: c1 58 subi r28, 0x81 ; 129
+ 9f4: d0 40 sbci r29, 0x00 ; 0
+ 9f6: 0f b6 in r0, 0x3f ; 63
+ 9f8: f8 94 cli
+ 9fa: de bf out 0x3e, r29 ; 62
+ 9fc: 0f be out 0x3f, r0 ; 63
+ 9fe: cd bf out 0x3d, r28 ; 61
+ a00: cf 57 subi r28, 0x7F ; 127
+ a02: df 4f sbci r29, 0xFF ; 255
+ a04: 88 83 st Y, r24
+ a06: c1 58 subi r28, 0x81 ; 129
+ a08: d0 40 sbci r29, 0x00 ; 0
+ a0a: 2b 01 movw r4, r22
+ a0c: 3a 01 movw r6, r20
+ a0e: 49 01 movw r8, r18
+ a10: 71 e4 ldi r23, 0x41 ; 65
+ a12: a7 2e mov r10, r23
+ a14: b1 2c mov r11, r1
+ a16: ac 0e add r10, r28
+ a18: bd 1e adc r11, r29
+ a1a: f5 01 movw r30, r10
+ a1c: 61 e8 ldi r22, 0x81 ; 129
+ a1e: c6 2e mov r12, r22
+ a20: d1 2c mov r13, r1
+ a22: cc 0e add r12, r28
+ a24: dd 1e adc r13, r29
+ int notdone2 = 1;
+ int sent = 0;
+
+ for (i=0;i<64;i++)
+ {
+ pos[i] = 0;
+ a26: 11 92 st Z+, r1
+ unsigned char pos[64];
+ int notdone = 1;
+ int notdone2 = 1;
+ int sent = 0;
+
+ for (i=0;i<64;i++)
+ a28: ec 15 cp r30, r12
+ a2a: fd 05 cpc r31, r13
+ a2c: e1 f7 brne .-8 ; 0xa26 <_Z32effect_boxside_randsend_parallelciii+0x5c>
+ a2e: 00 e0 ldi r16, 0x00 ; 0
+ a30: 10 e0 ldi r17, 0x00 ; 0
+ sent++;
+ }
+ }
+
+ done = 0;
+ for (i=0;i<64;i++)
+ a32: 1e 01 movw r2, r28
+ a34: 08 94 sec
+ a36: 21 1c adc r2, r1
+ a38: 31 1c adc r3, r1
+ pos[i] = 0;
+ }
+
+ while (notdone)
+ {
+ if (mode == 1)
+ a3a: 81 e0 ldi r24, 0x01 ; 1
+ a3c: 88 16 cp r8, r24
+ a3e: 91 04 cpc r9, r1
+ a40: b9 f4 brne .+46 ; 0xa70 <_Z32effect_boxside_randsend_parallelciii+0xa6>
+ a42: 12 c0 rjmp .+36 ; 0xa68 <_Z32effect_boxside_randsend_parallelciii+0x9e>
+ {
+ notdone2 = 1;
+ while (notdone2 && sent<64)
+ {
+ i = myrand()%64;
+ a44: 91 dc rcall .-1758 ; 0x368 <_Z6myrandv>
+ a46: 60 e4 ldi r22, 0x40 ; 64
+ a48: 70 e0 ldi r23, 0x00 ; 0
+ a4a: 5c d2 rcall .+1208 ; 0xf04 <__divmodhi4>
+ if (pos[i] == 0)
+ a4c: e1 e4 ldi r30, 0x41 ; 65
+ a4e: f0 e0 ldi r31, 0x00 ; 0
+ a50: ec 0f add r30, r28
+ a52: fd 1f adc r31, r29
+ a54: e8 0f add r30, r24
+ a56: f9 1f adc r31, r25
+ a58: 80 81 ld r24, Z
+ a5a: 88 23 and r24, r24
+ a5c: 99 f7 brne .-26 ; 0xa44 <_Z32effect_boxside_randsend_parallelciii+0x7a>
+ {
+ sent++;
+ a5e: 0f 5f subi r16, 0xFF ; 255
+ a60: 1f 4f sbci r17, 0xFF ; 255
+ pos[i] += 1;
+ a62: 91 e0 ldi r25, 0x01 ; 1
+ a64: 90 83 st Z, r25
+ a66: 16 c0 rjmp .+44 ; 0xa94 <_Z32effect_boxside_randsend_parallelciii+0xca>
+ while (notdone)
+ {
+ if (mode == 1)
+ {
+ notdone2 = 1;
+ while (notdone2 && sent<64)
+ a68: 00 34 cpi r16, 0x40 ; 64
+ a6a: 11 05 cpc r17, r1
+ a6c: 5c f3 brlt .-42 ; 0xa44 <_Z32effect_boxside_randsend_parallelciii+0x7a>
+ a6e: 12 c0 rjmp .+36 ; 0xa94 <_Z32effect_boxside_randsend_parallelciii+0xca>
+ sent++;
+ pos[i] += 1;
+ notdone2 = 0;
+ }
+ }
+ } else if (mode == 2)
+ a70: 82 e0 ldi r24, 0x02 ; 2
+ a72: 88 16 cp r8, r24
+ a74: 91 04 cpc r9, r1
+ a76: 71 f4 brne .+28 ; 0xa94 <_Z32effect_boxside_randsend_parallelciii+0xca>
+ {
+ if (sent<64)
+ a78: 00 34 cpi r16, 0x40 ; 64
+ a7a: 11 05 cpc r17, r1
+ a7c: 5c f4 brge .+22 ; 0xa94 <_Z32effect_boxside_randsend_parallelciii+0xca>
+ {
+ pos[sent] += 1;
+ a7e: e1 e4 ldi r30, 0x41 ; 65
+ a80: f0 e0 ldi r31, 0x00 ; 0
+ a82: ec 0f add r30, r28
+ a84: fd 1f adc r31, r29
+ a86: e0 0f add r30, r16
+ a88: f1 1f adc r31, r17
+ a8a: 80 81 ld r24, Z
+ a8c: 8f 5f subi r24, 0xFF ; 255
+ a8e: 80 83 st Z, r24
+ sent++;
+ a90: 0f 5f subi r16, 0xFF ; 255
+ a92: 1f 4f sbci r17, 0xFF ; 255
+ a94: f5 01 movw r30, r10
+ a96: ee 24 eor r14, r14
+ a98: ff 24 eor r15, r15
+ }
+
+ done = 0;
+ for (i=0;i<64;i++)
+ {
+ if (pos[i] > 0 && pos[i] <7)
+ a9a: 90 81 ld r25, Z
+ a9c: 89 2f mov r24, r25
+ a9e: 81 50 subi r24, 0x01 ; 1
+ aa0: 86 30 cpi r24, 0x06 ; 6
+ aa2: 10 f4 brcc .+4 ; 0xaa8 <_Z32effect_boxside_randsend_parallelciii+0xde>
+ {
+ pos[i] += 1;
+ aa4: 9f 5f subi r25, 0xFF ; 255
+ aa6: 90 83 st Z, r25
+ }
+
+ if (pos[i] == 7)
+ aa8: 80 81 ld r24, Z
+ aaa: 87 30 cpi r24, 0x07 ; 7
+ aac: 19 f4 brne .+6 ; 0xab4 <_Z32effect_boxside_randsend_parallelciii+0xea>
+ done++;
+ aae: 08 94 sec
+ ab0: e1 1c adc r14, r1
+ ab2: f1 1c adc r15, r1
+ ab4: 31 96 adiw r30, 0x01 ; 1
+ sent++;
+ }
+ }
+
+ done = 0;
+ for (i=0;i<64;i++)
+ ab6: ec 15 cp r30, r12
+ ab8: fd 05 cpc r31, r13
+ aba: 79 f7 brne .-34 ; 0xa9a <_Z32effect_boxside_randsend_parallelciii+0xd0>
+ abc: d1 01 movw r26, r2
+ abe: f5 01 movw r30, r10
+ ac0: 80 81 ld r24, Z
+ if (done == 64)
+ notdone = 0;
+
+ for (i=0;i<64;i++)
+ {
+ if (origin == 0)
+ ac2: 41 14 cp r4, r1
+ ac4: 51 04 cpc r5, r1
+ ac6: 19 f0 breq .+6 ; 0xace <_Z32effect_boxside_randsend_parallelciii+0x104>
+ {
+ cubepos[i] = pos[i];
+ } else
+ {
+ cubepos[i] = (7-pos[i]);
+ ac8: 97 e0 ldi r25, 0x07 ; 7
+ aca: 98 1b sub r25, r24
+ acc: 89 2f mov r24, r25
+ ace: 8c 93 st X, r24
+ ad0: 31 96 adiw r30, 0x01 ; 1
+ ad2: 11 96 adiw r26, 0x01 ; 1
+ }
+
+ if (done == 64)
+ notdone = 0;
+
+ for (i=0;i<64;i++)
+ ad4: ec 15 cp r30, r12
+ ad6: fd 05 cpc r31, r13
+ ad8: 99 f7 brne .-26 ; 0xac0 <_Z32effect_boxside_randsend_parallelciii+0xf6>
+ cubepos[i] = (7-pos[i]);
+ }
+ }
+
+
+ delay_ms(delay);
+ ada: c3 01 movw r24, r6
+ adc: ec dc rcall .-1576 ; 0x4b6 <_Z8delay_msj>
+ draw_positions_axis(axis,cubepos,0);
+ ade: cf 57 subi r28, 0x7F ; 127
+ ae0: df 4f sbci r29, 0xFF ; 255
+ ae2: 88 81 ld r24, Y
+ ae4: c1 58 subi r28, 0x81 ; 129
+ ae6: d0 40 sbci r29, 0x00 ; 0
+ ae8: b1 01 movw r22, r2
+ aea: 40 e0 ldi r20, 0x00 ; 0
+ aec: 50 e0 ldi r21, 0x00 ; 0
+ aee: 05 df rcall .-502 ; 0x8fa <_Z19draw_positions_axiscPhi>
+ LED_PORT ^= LED_RED;
+ af0: 82 b3 in r24, 0x12 ; 18
+ af2: 94 e0 ldi r25, 0x04 ; 4
+ af4: 89 27 eor r24, r25
+ af6: 82 bb out 0x12, r24 ; 18
+ for (i=0;i<64;i++)
+ {
+ pos[i] = 0;
+ }
+
+ while (notdone)
+ af8: 80 e4 ldi r24, 0x40 ; 64
+ afa: e8 16 cp r14, r24
+ afc: f1 04 cpc r15, r1
+ afe: 09 f0 breq .+2 ; 0xb02 <_Z32effect_boxside_randsend_parallelciii+0x138>
+ b00: 9c cf rjmp .-200 ; 0xa3a <_Z32effect_boxside_randsend_parallelciii+0x70>
+ delay_ms(delay);
+ draw_positions_axis(axis,cubepos,0);
+ LED_PORT ^= LED_RED;
+ }
+
+}
+ b02: cf 57 subi r28, 0x7F ; 127
+ b04: df 4f sbci r29, 0xFF ; 255
+ b06: 0f b6 in r0, 0x3f ; 63
+ b08: f8 94 cli
+ b0a: de bf out 0x3e, r29 ; 62
+ b0c: 0f be out 0x3f, r0 ; 63
+ b0e: cd bf out 0x3d, r28 ; 61
+ b10: cf 91 pop r28
+ b12: df 91 pop r29
+ b14: 1f 91 pop r17
+ b16: 0f 91 pop r16
+ b18: ff 90 pop r15
+ b1a: ef 90 pop r14
+ b1c: df 90 pop r13
+ b1e: cf 90 pop r12
+ b20: bf 90 pop r11
+ b22: af 90 pop r10
+ b24: 9f 90 pop r9
+ b26: 8f 90 pop r8
+ b28: 7f 90 pop r7
+ b2a: 6f 90 pop r6
+ b2c: 5f 90 pop r5
+ b2e: 4f 90 pop r4
+ b30: 3f 90 pop r3
+ b32: 2f 90 pop r2
+ b34: 08 95 ret
+
+00000b36 <_Z20effect_z_updown_movePhS_c>:
+
+ }
+
+}
+
+void effect_z_updown_move (unsigned char positions[64], unsigned char destinations[64], char axis)
+ b36: ac 01 movw r20, r24
+ b38: dc 01 movw r26, r24
+ b3a: fb 01 movw r30, r22
+ b3c: 20 e0 ldi r18, 0x00 ; 0
+ b3e: 30 e0 ldi r19, 0x00 ; 0
+{
+ int px;
+ for (px=0; px<64; px++)
+ {
+ if (positions[px]<destinations[px])
+ b40: 9c 91 ld r25, X
+ b42: 80 81 ld r24, Z
+ b44: 98 17 cp r25, r24
+ b46: 10 f4 brcc .+4 ; 0xb4c <_Z20effect_z_updown_movePhS_c+0x16>
+ {
+ positions[px]++;
+ b48: 9f 5f subi r25, 0xFF ; 255
+ b4a: 9c 93 st X, r25
+ }
+ if (positions[px]>destinations[px])
+ b4c: 9c 91 ld r25, X
+ b4e: 80 81 ld r24, Z
+ b50: 89 17 cp r24, r25
+ b52: 10 f4 brcc .+4 ; 0xb58 <_Z20effect_z_updown_movePhS_c+0x22>
+ {
+ positions[px]--;
+ b54: 91 50 subi r25, 0x01 ; 1
+ b56: 9c 93 st X, r25
+}
+
+void effect_z_updown_move (unsigned char positions[64], unsigned char destinations[64], char axis)
+{
+ int px;
+ for (px=0; px<64; px++)
+ b58: 2f 5f subi r18, 0xFF ; 255
+ b5a: 3f 4f sbci r19, 0xFF ; 255
+ b5c: 11 96 adiw r26, 0x01 ; 1
+ b5e: 31 96 adiw r30, 0x01 ; 1
+ b60: 20 34 cpi r18, 0x40 ; 64
+ b62: 31 05 cpc r19, r1
+ b64: 69 f7 brne .-38 ; 0xb40 <_Z20effect_z_updown_movePhS_c+0xa>
+ {
+ positions[px]--;
+ }
+ }
+
+ draw_positions_axis (AXIS_Z, positions,0);
+ b66: 8a e7 ldi r24, 0x7A ; 122
+ b68: ba 01 movw r22, r20
+ b6a: 40 e0 ldi r20, 0x00 ; 0
+ b6c: 50 e0 ldi r21, 0x00 ; 0
+ b6e: c5 de rcall .-630 ; 0x8fa <_Z19draw_positions_axiscPhi>
+}
+ b70: 08 95 ret
+
+00000b72 <_Z15effect_z_updownii>:
+ delay_ms(1000);
+ shift(AXIS_Z,-1);
+ }
+}
+
+void effect_z_updown (int iterations, int delay)
+ b72: 2f 92 push r2
+ b74: 3f 92 push r3
+ b76: 4f 92 push r4
+ b78: 5f 92 push r5
+ b7a: 6f 92 push r6
+ b7c: 7f 92 push r7
+ b7e: 8f 92 push r8
+ b80: 9f 92 push r9
+ b82: af 92 push r10
+ b84: bf 92 push r11
+ b86: cf 92 push r12
+ b88: df 92 push r13
+ b8a: ef 92 push r14
+ b8c: ff 92 push r15
+ b8e: 0f 93 push r16
+ b90: 1f 93 push r17
+ b92: df 93 push r29
+ b94: cf 93 push r28
+ b96: cd b7 in r28, 0x3d ; 61
+ b98: de b7 in r29, 0x3e ; 62
+ b9a: c0 58 subi r28, 0x80 ; 128
+ b9c: d0 40 sbci r29, 0x00 ; 0
+ b9e: 0f b6 in r0, 0x3f ; 63
+ ba0: f8 94 cli
+ ba2: de bf out 0x3e, r29 ; 62
+ ba4: 0f be out 0x3f, r0 ; 63
+ ba6: cd bf out 0x3d, r28 ; 61
+ ba8: 2c 01 movw r4, r24
+ baa: 7b 01 movw r14, r22
+ bac: 00 e0 ldi r16, 0x00 ; 0
+ bae: 10 e0 ldi r17, 0x00 ; 0
+
+ int i,y,move;
+
+ for (i=0; i<64; i++)
+ {
+ positions[i] = 4;
+ bb0: 5e 01 movw r10, r28
+ bb2: 08 94 sec
+ bb4: a1 1c adc r10, r1
+ bb6: b1 1c adc r11, r1
+ bb8: 24 e0 ldi r18, 0x04 ; 4
+ bba: 92 2e mov r9, r18
+ destinations[i] = myrand()%8;
+ bbc: 91 e4 ldi r25, 0x41 ; 65
+ bbe: c9 2e mov r12, r25
+ bc0: d1 2c mov r13, r1
+ bc2: cc 0e add r12, r28
+ bc4: dd 1e adc r13, r29
+
+ int i,y,move;
+
+ for (i=0; i<64; i++)
+ {
+ positions[i] = 4;
+ bc6: f5 01 movw r30, r10
+ bc8: e0 0f add r30, r16
+ bca: f1 1f adc r31, r17
+ bcc: 90 82 st Z, r9
+ destinations[i] = myrand()%8;
+ bce: cc db rcall .-2152 ; 0x368 <_Z6myrandv>
+ bd0: f6 01 movw r30, r12
+ bd2: e0 0f add r30, r16
+ bd4: f1 1f adc r31, r17
+ bd6: 68 e0 ldi r22, 0x08 ; 8
+ bd8: 70 e0 ldi r23, 0x00 ; 0
+ bda: 94 d1 rcall .+808 ; 0xf04 <__divmodhi4>
+ bdc: 80 83 st Z, r24
+ unsigned char positions[64];
+ unsigned char destinations[64];
+
+ int i,y,move;
+
+ for (i=0; i<64; i++)
+ bde: 0f 5f subi r16, 0xFF ; 255
+ be0: 1f 4f sbci r17, 0xFF ; 255
+ be2: 00 34 cpi r16, 0x40 ; 64
+ be4: 11 05 cpc r17, r1
+ be6: 79 f7 brne .-34 ; 0xbc6 <_Z15effect_z_updownii+0x54>
+ be8: 00 e0 ldi r16, 0x00 ; 0
+ bea: 10 e0 ldi r17, 0x00 ; 0
+ destinations[i] = myrand()%8;
+ }
+
+ for (i=0; i<8; i++)
+ {
+ effect_z_updown_move(positions, destinations, AXIS_Z);
+ bec: 81 e4 ldi r24, 0x41 ; 65
+ bee: a8 2e mov r10, r24
+ bf0: b1 2c mov r11, r1
+ bf2: ac 0e add r10, r28
+ bf4: bd 1e adc r11, r29
+ bf6: 6e 01 movw r12, r28
+ bf8: 08 94 sec
+ bfa: c1 1c adc r12, r1
+ bfc: d1 1c adc r13, r1
+ delay_ms(delay);
+ bfe: 37 01 movw r6, r14
+ destinations[i] = myrand()%8;
+ }
+
+ for (i=0; i<8; i++)
+ {
+ effect_z_updown_move(positions, destinations, AXIS_Z);
+ c00: c6 01 movw r24, r12
+ c02: b5 01 movw r22, r10
+ c04: 4a e7 ldi r20, 0x7A ; 122
+ c06: 97 df rcall .-210 ; 0xb36 <_Z20effect_z_updown_movePhS_c>
+ delay_ms(delay);
+ c08: c3 01 movw r24, r6
+ c0a: 55 dc rcall .-1878 ; 0x4b6 <_Z8delay_msj>
+ {
+ positions[i] = 4;
+ destinations[i] = myrand()%8;
+ }
+
+ for (i=0; i<8; i++)
+ c0c: 0f 5f subi r16, 0xFF ; 255
+ c0e: 1f 4f sbci r17, 0xFF ; 255
+ c10: 08 30 cpi r16, 0x08 ; 8
+ c12: 11 05 cpc r17, r1
+ c14: a9 f7 brne .-22 ; 0xc00 <_Z15effect_z_updownii+0x8e>
+ {
+ effect_z_updown_move(positions, destinations, AXIS_Z);
+ delay_ms(delay);
+ }
+
+ delay_ms(delay*4);
+ c16: 57 01 movw r10, r14
+ c18: aa 0c add r10, r10
+ c1a: bb 1c adc r11, r11
+ c1c: aa 0c add r10, r10
+ c1e: bb 1c adc r11, r11
+ c20: cc 24 eor r12, r12
+ c22: dd 24 eor r13, r13
+
+ for (i=0;i<iterations;i++)
+ {
+ for (move=0;move<8;move++)
+ {
+ effect_z_updown_move(positions, destinations, AXIS_Z);
+ c24: a1 e4 ldi r26, 0x41 ; 65
+ c26: 8a 2e mov r8, r26
+ c28: 91 2c mov r9, r1
+ c2a: 8c 0e add r8, r28
+ c2c: 9d 1e adc r9, r29
+ c2e: 1e 01 movw r2, r28
+ c30: 08 94 sec
+ c32: 21 1c adc r2, r1
+ c34: 31 1c adc r3, r1
+ c36: 2b c0 rjmp .+86 ; 0xc8e <_Z15effect_z_updownii+0x11c>
+ delay_ms(delay);
+ }
+
+ delay_ms(delay*4);
+ c38: 00 e0 ldi r16, 0x00 ; 0
+ c3a: 10 e0 ldi r17, 0x00 ; 0
+
+ for (i=0;i<iterations;i++)
+ {
+ for (move=0;move<8;move++)
+ {
+ effect_z_updown_move(positions, destinations, AXIS_Z);
+ c3c: c1 01 movw r24, r2
+ c3e: b4 01 movw r22, r8
+ c40: 4a e7 ldi r20, 0x7A ; 122
+ c42: 79 df rcall .-270 ; 0xb36 <_Z20effect_z_updown_movePhS_c>
+ delay_ms(delay);
+ c44: c3 01 movw r24, r6
+ c46: 37 dc rcall .-1938 ; 0x4b6 <_Z8delay_msj>
+ delay_ms(delay);
+ }
+
+ for (i=0;i<iterations;i++)
+ {
+ for (move=0;move<8;move++)
+ c48: 0f 5f subi r16, 0xFF ; 255
+ c4a: 1f 4f sbci r17, 0xFF ; 255
+ c4c: 08 30 cpi r16, 0x08 ; 8
+ c4e: 11 05 cpc r17, r1
+ c50: a9 f7 brne .-22 ; 0xc3c <_Z15effect_z_updownii+0xca>
+ {
+ effect_z_updown_move(positions, destinations, AXIS_Z);
+ delay_ms(delay);
+ }
+
+ delay_ms(delay*4);
+ c52: c5 01 movw r24, r10
+ c54: 30 dc rcall .-1952 ; 0x4b6 <_Z8delay_msj>
+ c56: ee 24 eor r14, r14
+ c58: ff 24 eor r15, r15
+
+
+ for (y=0;y<32;y++)
+ {
+ destinations[myrand()%64] = myrand()%8;
+ c5a: 86 db rcall .-2292 ; 0x368 <_Z6myrandv>
+ c5c: 8c 01 movw r16, r24
+ c5e: 84 db rcall .-2296 ; 0x368 <_Z6myrandv>
+ c60: 9c 01 movw r18, r24
+ c62: c8 01 movw r24, r16
+ c64: 60 e4 ldi r22, 0x40 ; 64
+ c66: 70 e0 ldi r23, 0x00 ; 0
+ c68: 4d d1 rcall .+666 ; 0xf04 <__divmodhi4>
+ c6a: f4 01 movw r30, r8
+ c6c: e8 0f add r30, r24
+ c6e: f9 1f adc r31, r25
+ c70: c9 01 movw r24, r18
+ c72: 68 e0 ldi r22, 0x08 ; 8
+ c74: 70 e0 ldi r23, 0x00 ; 0
+ c76: 46 d1 rcall .+652 ; 0xf04 <__divmodhi4>
+ c78: 80 83 st Z, r24
+ }
+
+ delay_ms(delay*4);
+
+
+ for (y=0;y<32;y++)
+ c7a: 08 94 sec
+ c7c: e1 1c adc r14, r1
+ c7e: f1 1c adc r15, r1
+ c80: 80 e2 ldi r24, 0x20 ; 32
+ c82: e8 16 cp r14, r24
+ c84: f1 04 cpc r15, r1
+ c86: 49 f7 brne .-46 ; 0xc5a <_Z15effect_z_updownii+0xe8>
+ {
+ effect_z_updown_move(positions, destinations, AXIS_Z);
+ delay_ms(delay);
+ }
+
+ for (i=0;i<iterations;i++)
+ c88: 08 94 sec
+ c8a: c1 1c adc r12, r1
+ c8c: d1 1c adc r13, r1
+ c8e: c4 14 cp r12, r4
+ c90: d5 04 cpc r13, r5
+ c92: 94 f2 brlt .-92 ; 0xc38 <_Z15effect_z_updownii+0xc6>
+ destinations[myrand()%64] = myrand()%8;
+ }
+
+ }
+
+}
+ c94: c0 58 subi r28, 0x80 ; 128
+ c96: df 4f sbci r29, 0xFF ; 255
+ c98: 0f b6 in r0, 0x3f ; 63
+ c9a: f8 94 cli
+ c9c: de bf out 0x3e, r29 ; 62
+ c9e: 0f be out 0x3f, r0 ; 63
+ ca0: cd bf out 0x3d, r28 ; 61
+ ca2: cf 91 pop r28
+ ca4: df 91 pop r29
+ ca6: 1f 91 pop r17
+ ca8: 0f 91 pop r16
+ caa: ff 90 pop r15
+ cac: ef 90 pop r14
+ cae: df 90 pop r13
+ cb0: cf 90 pop r12
+ cb2: bf 90 pop r11
+ cb4: af 90 pop r10
+ cb6: 9f 90 pop r9
+ cb8: 8f 90 pop r8
+ cba: 7f 90 pop r7
+ cbc: 6f 90 pop r6
+ cbe: 5f 90 pop r5
+ cc0: 4f 90 pop r4
+ cc2: 3f 90 pop r3
+ cc4: 2f 90 pop r2
+ cc6: 08 95 ret
+
+00000cc8 <_Z20effect_random_fillerii>:
+ iterations--;
+ }
+}
+
+// Set or clear exactly 512 voxels in a random order.
+void effect_random_filler (int delay, int state)
+ cc8: 8f 92 push r8
+ cca: 9f 92 push r9
+ ccc: af 92 push r10
+ cce: bf 92 push r11
+ cd0: cf 92 push r12
+ cd2: df 92 push r13
+ cd4: ef 92 push r14
+ cd6: ff 92 push r15
+ cd8: 0f 93 push r16
+ cda: 1f 93 push r17
+ cdc: cf 93 push r28
+ cde: df 93 push r29
+ ce0: 4c 01 movw r8, r24
+ ce2: 8b 01 movw r16, r22
+{
+ int x,y,z;
+ int loop = 0;
+
+
+ if (state == 1)
+ ce4: 61 30 cpi r22, 0x01 ; 1
+ ce6: 71 05 cpc r23, r1
+ ce8: 11 f4 brne .+4 ; 0xcee <_Z20effect_random_fillerii+0x26>
+ {
+ fill(0x00);
+ cea: 80 e0 ldi r24, 0x00 ; 0
+ cec: 01 c0 rjmp .+2 ; 0xcf0 <_Z20effect_random_fillerii+0x28>
+ } else
+ {
+ fill(0xff);
+ cee: 8f ef ldi r24, 0xFF ; 255
+ cf0: c5 db rcall .-2166 ; 0x47c <_Z4fillh>
+ cf2: c0 e0 ldi r28, 0x00 ; 0
+ cf4: d0 e0 ldi r29, 0x00 ; 0
+ }
+
+ while (loop<511)
+ {
+ x = myrand()%8;
+ cf6: 38 db rcall .-2448 ; 0x368 <_Z6myrandv>
+ cf8: 68 e0 ldi r22, 0x08 ; 8
+ cfa: 70 e0 ldi r23, 0x00 ; 0
+ cfc: 03 d1 rcall .+518 ; 0xf04 <__divmodhi4>
+ cfe: b8 2e mov r11, r24
+ d00: a9 2e mov r10, r25
+ y = myrand()%8;
+ d02: 32 db rcall .-2460 ; 0x368 <_Z6myrandv>
+ d04: 68 e0 ldi r22, 0x08 ; 8
+ d06: 70 e0 ldi r23, 0x00 ; 0
+ d08: fd d0 rcall .+506 ; 0xf04 <__divmodhi4>
+ d0a: d8 2e mov r13, r24
+ d0c: c9 2e mov r12, r25
+ z = myrand()%8;
+ d0e: 2c db rcall .-2472 ; 0x368 <_Z6myrandv>
+ d10: 68 e0 ldi r22, 0x08 ; 8
+ d12: 70 e0 ldi r23, 0x00 ; 0
+ d14: f7 d0 rcall .+494 ; 0xf04 <__divmodhi4>
+ d16: f8 2e mov r15, r24
+ d18: e9 2e mov r14, r25
+
+ if ((state == 0 && getvoxel(x,y,z) == 0x01) || (state == 1 && getvoxel(x,y,z) == 0x00))
+ d1a: 01 15 cp r16, r1
+ d1c: 11 05 cpc r17, r1
+ d1e: 51 f4 brne .+20 ; 0xd34 <_Z20effect_random_fillerii+0x6c>
+ d20: 8b 2d mov r24, r11
+ d22: 9a 2d mov r25, r10
+ d24: 6d 2d mov r22, r13
+ d26: 7c 2d mov r23, r12
+ d28: 4f 2d mov r20, r15
+ d2a: 5e 2d mov r21, r14
+ d2c: 7e db rcall .-2308 ; 0x42a <_Z8getvoxeliii>
+ d2e: 81 30 cpi r24, 0x01 ; 1
+ d30: 11 f7 brne .-60 ; 0xcf6 <_Z20effect_random_fillerii+0x2e>
+ d32: 0c c0 rjmp .+24 ; 0xd4c <_Z20effect_random_fillerii+0x84>
+ d34: 01 30 cpi r16, 0x01 ; 1
+ d36: 11 05 cpc r17, r1
+ d38: f1 f6 brne .-68 ; 0xcf6 <_Z20effect_random_fillerii+0x2e>
+ d3a: 8b 2d mov r24, r11
+ d3c: 9a 2d mov r25, r10
+ d3e: 6d 2d mov r22, r13
+ d40: 7c 2d mov r23, r12
+ d42: 4f 2d mov r20, r15
+ d44: 5e 2d mov r21, r14
+ d46: 71 db rcall .-2334 ; 0x42a <_Z8getvoxeliii>
+ d48: 88 23 and r24, r24
+ d4a: a9 f6 brne .-86 ; 0xcf6 <_Z20effect_random_fillerii+0x2e>
+ {
+ altervoxel(x,y,z,state);
+ d4c: 8b 2d mov r24, r11
+ d4e: 9a 2d mov r25, r10
+ d50: 6d 2d mov r22, r13
+ d52: 7c 2d mov r23, r12
+ d54: 4f 2d mov r20, r15
+ d56: 5e 2d mov r21, r14
+ d58: 98 01 movw r18, r16
+ d5a: 89 db rcall .-2286 ; 0x46e <_Z10altervoxeliiii>
+ delay_ms(delay);
+ d5c: c4 01 movw r24, r8
+ d5e: ab db rcall .-2218 ; 0x4b6 <_Z8delay_msj>
+ loop++;
+ d60: 21 96 adiw r28, 0x01 ; 1
+ } else
+ {
+ fill(0xff);
+ }
+
+ while (loop<511)
+ d62: 81 e0 ldi r24, 0x01 ; 1
+ d64: cf 3f cpi r28, 0xFF ; 255
+ d66: d8 07 cpc r29, r24
+ d68: 31 f6 brne .-116 ; 0xcf6 <_Z20effect_random_fillerii+0x2e>
+ altervoxel(x,y,z,state);
+ delay_ms(delay);
+ loop++;
+ }
+ }
+}
+ d6a: df 91 pop r29
+ d6c: cf 91 pop r28
+ d6e: 1f 91 pop r17
+ d70: 0f 91 pop r16
+ d72: ff 90 pop r15
+ d74: ef 90 pop r14
+ d76: df 90 pop r13
+ d78: cf 90 pop r12
+ d7a: bf 90 pop r11
+ d7c: af 90 pop r10
+ d7e: 9f 90 pop r9
+ d80: 8f 90 pop r8
+ d82: 08 95 ret
+
+00000d84 <_Z17sendvoxels_rand_ziii>:
+ }
+}
+
+// For each coordinate along X and Y, a voxel is set either at level 0 or at level 7
+// for n iterations, a random voxel is sent to the opposite side of where it was.
+void sendvoxels_rand_z (int iterations, int delay, int wait)
+ d84: 6f 92 push r6
+ d86: 7f 92 push r7
+ d88: 8f 92 push r8
+ d8a: 9f 92 push r9
+ d8c: af 92 push r10
+ d8e: bf 92 push r11
+ d90: df 92 push r13
+ d92: ef 92 push r14
+ d94: ff 92 push r15
+ d96: 0f 93 push r16
+ d98: 1f 93 push r17
+ d9a: cf 93 push r28
+ d9c: df 93 push r29
+ d9e: 3c 01 movw r6, r24
+ da0: 5b 01 movw r10, r22
+ da2: 4a 01 movw r8, r20
+{
+ unsigned char x, y, last_x = 0, last_y = 0, i;
+
+ fill(0x00);
+ da4: 80 e0 ldi r24, 0x00 ; 0
+ da6: 6a db rcall .-2348 ; 0x47c <_Z4fillh>
+ da8: 00 e0 ldi r16, 0x00 ; 0
+ daa: 10 e0 ldi r17, 0x00 ; 0
+ dac: 1c c0 rjmp .+56 ; 0xde6 <_Z17sendvoxels_rand_ziii+0x62>
+ {
+ for (y=0;y<8;y++)
+ {
+ // Then set a voxel either at the top or at the bottom
+ // myrand()%2 returns either 0 or 1. multiplying by 7 gives either 0 or 7.
+ setvoxel(x,y,((myrand()%2)*7));
+ dae: dc da rcall .-2632 ; 0x368 <_Z6myrandv>
+ db0: 62 e0 ldi r22, 0x02 ; 2
+ db2: 70 e0 ldi r23, 0x00 ; 0
+ db4: a7 d0 rcall .+334 ; 0xf04 <__divmodhi4>
+ db6: ac 01 movw r20, r24
+ db8: 33 e0 ldi r19, 0x03 ; 3
+ dba: 44 0f add r20, r20
+ dbc: 55 1f adc r21, r21
+ dbe: 3a 95 dec r19
+ dc0: e1 f7 brne .-8 ; 0xdba <_Z17sendvoxels_rand_ziii+0x36>
+ dc2: 48 1b sub r20, r24
+ dc4: 59 0b sbc r21, r25
+ dc6: c8 01 movw r24, r16
+ dc8: be 01 movw r22, r28
+ dca: 0a db rcall .-2540 ; 0x3e0 <_Z8setvoxeliii>
+ dcc: 21 96 adiw r28, 0x01 ; 1
+ fill(0x00);
+
+ // Loop through all the X and Y coordinates
+ for (x=0;x<8;x++)
+ {
+ for (y=0;y<8;y++)
+ dce: c8 30 cpi r28, 0x08 ; 8
+ dd0: d1 05 cpc r29, r1
+ dd2: 69 f7 brne .-38 ; 0xdae <_Z17sendvoxels_rand_ziii+0x2a>
+ dd4: 0f 5f subi r16, 0xFF ; 255
+ dd6: 1f 4f sbci r17, 0xFF ; 255
+ unsigned char x, y, last_x = 0, last_y = 0, i;
+
+ fill(0x00);
+
+ // Loop through all the X and Y coordinates
+ for (x=0;x<8;x++)
+ dd8: 08 30 cpi r16, 0x08 ; 8
+ dda: 11 05 cpc r17, r1
+ ddc: 21 f4 brne .+8 ; 0xde6 <_Z17sendvoxels_rand_ziii+0x62>
+ dde: dd 24 eor r13, r13
+ de0: ee 24 eor r14, r14
+ de2: ff 24 eor r15, r15
+ de4: 29 c0 rjmp .+82 ; 0xe38 <_Z17sendvoxels_rand_ziii+0xb4>
+ de6: c0 e0 ldi r28, 0x00 ; 0
+ de8: d0 e0 ldi r29, 0x00 ; 0
+ dea: e1 cf rjmp .-62 ; 0xdae <_Z17sendvoxels_rand_ziii+0x2a>
+ }
+
+ for (i=0;i<iterations;i++)
+ {
+ // Pick a random x,y position
+ x = myrand()%8;
+ dec: bd da rcall .-2694 ; 0x368 <_Z6myrandv>
+ dee: ec 01 movw r28, r24
+ y = myrand()%8;
+ df0: bb da rcall .-2698 ; 0x368 <_Z6myrandv>
+ df2: 68 e0 ldi r22, 0x08 ; 8
+ df4: 70 e0 ldi r23, 0x00 ; 0
+ df6: 86 d0 rcall .+268 ; 0xf04 <__divmodhi4>
+ df8: 08 2f mov r16, r24
+ // but not the sameone twice in a row
+ if (y != last_y && x != last_x)
+ dfa: 8e 15 cp r24, r14
+ dfc: e1 f0 breq .+56 ; 0xe36 <_Z17sendvoxels_rand_ziii+0xb2>
+ }
+
+ for (i=0;i<iterations;i++)
+ {
+ // Pick a random x,y position
+ x = myrand()%8;
+ dfe: ce 01 movw r24, r28
+ e00: 68 e0 ldi r22, 0x08 ; 8
+ e02: 70 e0 ldi r23, 0x00 ; 0
+ e04: 7f d0 rcall .+254 ; 0xf04 <__divmodhi4>
+ e06: 18 2f mov r17, r24
+ y = myrand()%8;
+ // but not the sameone twice in a row
+ if (y != last_y && x != last_x)
+ e08: 8d 15 cp r24, r13
+ e0a: a9 f0 breq .+42 ; 0xe36 <_Z17sendvoxels_rand_ziii+0xb2>
+ {
+ // If the voxel at this x,y is at the bottom
+ if (getvoxel(x,y,0))
+ e0c: 90 e0 ldi r25, 0x00 ; 0
+ e0e: 60 2f mov r22, r16
+ e10: 70 e0 ldi r23, 0x00 ; 0
+ e12: 40 e0 ldi r20, 0x00 ; 0
+ e14: 50 e0 ldi r21, 0x00 ; 0
+ e16: 09 db rcall .-2542 ; 0x42a <_Z8getvoxeliii>
+ e18: 88 23 and r24, r24
+ e1a: 21 f0 breq .+8 ; 0xe24 <_Z17sendvoxels_rand_ziii+0xa0>
+ {
+ // send it to the top
+ sendvoxel_z(x,y,0,delay);
+ e1c: 81 2f mov r24, r17
+ e1e: 60 2f mov r22, r16
+ e20: 40 e0 ldi r20, 0x00 ; 0
+ e22: 03 c0 rjmp .+6 ; 0xe2a <_Z17sendvoxels_rand_ziii+0xa6>
+ } else
+ {
+ // if its at the top, send it to the bottom
+ sendvoxel_z(x,y,7,delay);
+ e24: 81 2f mov r24, r17
+ e26: 60 2f mov r22, r16
+ e28: 47 e0 ldi r20, 0x07 ; 7
+ e2a: 95 01 movw r18, r10
+ e2c: 1b dd rcall .-1482 ; 0x864 <_Z11sendvoxel_zhhhi>
+ }
+ delay_ms(wait);
+ e2e: c4 01 movw r24, r8
+ e30: 42 db rcall .-2428 ; 0x4b6 <_Z8delay_msj>
+ e32: d1 2e mov r13, r17
+ e34: e0 2e mov r14, r16
+ // myrand()%2 returns either 0 or 1. multiplying by 7 gives either 0 or 7.
+ setvoxel(x,y,((myrand()%2)*7));
+ }
+ }
+
+ for (i=0;i<iterations;i++)
+ e36: f3 94 inc r15
+ e38: 8f 2d mov r24, r15
+ e3a: 90 e0 ldi r25, 0x00 ; 0
+ e3c: 86 15 cp r24, r6
+ e3e: 97 05 cpc r25, r7
+ e40: ac f2 brlt .-86 ; 0xdec <_Z17sendvoxels_rand_ziii+0x68>
+ last_y = y;
+ last_x = x;
+ }
+ }
+
+}
+ e42: df 91 pop r29
+ e44: cf 91 pop r28
+ e46: 1f 91 pop r17
+ e48: 0f 91 pop r16
+ e4a: ff 90 pop r15
+ e4c: ef 90 pop r14
+ e4e: df 90 pop r13
+ e50: bf 90 pop r11
+ e52: af 90 pop r10
+ e54: 9f 90 pop r9
+ e56: 8f 90 pop r8
+ e58: 7f 90 pop r7
+ e5a: 6f 90 pop r6
+ e5c: 08 95 ret
+
+00000e5e <_Z14effect_blinky2v>:
+ setplane(plane,i);
+ delay_ms(speed);
+ }
+}
+
+void effect_blinky2()
+ e5e: ef 92 push r14
+ e60: ff 92 push r15
+ e62: 0f 93 push r16
+ e64: 1f 93 push r17
+ e66: cf 93 push r28
+ e68: df 93 push r29
+{
+ int i,r;
+ fill(0x00);
+ e6a: 80 e0 ldi r24, 0x00 ; 0
+ e6c: 07 db rcall .-2546 ; 0x47c <_Z4fillh>
+ e6e: 00 e0 ldi r16, 0x00 ; 0
+ e70: 10 e0 ldi r17, 0x00 ; 0
+
+ i = 750;
+ while (i>0)
+ {
+ fill(0x00);
+ delay_ms(751-i);
+ e72: 4f ee ldi r20, 0xEF ; 239
+ e74: e4 2e mov r14, r20
+ e76: 42 e0 ldi r20, 0x02 ; 2
+ e78: f4 2e mov r15, r20
+ e7a: 3a c0 rjmp .+116 ; 0xef0 <_Z14effect_blinky2v+0x92>
+ for (r=0;r<2;r++)
+ {
+ i = 750;
+ while (i>0)
+ {
+ fill(0x00);
+ e7c: 80 e0 ldi r24, 0x00 ; 0
+ e7e: fe da rcall .-2564 ; 0x47c <_Z4fillh>
+ delay_ms(i);
+ e80: ce 01 movw r24, r28
+ e82: 19 db rcall .-2510 ; 0x4b6 <_Z8delay_msj>
+
+ fill(0xff);
+ e84: 8f ef ldi r24, 0xFF ; 255
+ e86: fa da rcall .-2572 ; 0x47c <_Z4fillh>
+ delay_ms(100);
+ e88: 84 e6 ldi r24, 0x64 ; 100
+ e8a: 90 e0 ldi r25, 0x00 ; 0
+ e8c: 14 db rcall .-2520 ; 0x4b6 <_Z8delay_msj>
+
+ i = i - (15+(1000/(i/10)));
+ e8e: ce 01 movw r24, r28
+ e90: 66 ef ldi r22, 0xF6 ; 246
+ e92: 7f ef ldi r23, 0xFF ; 255
+ e94: 37 d0 rcall .+110 ; 0xf04 <__divmodhi4>
+ e96: 88 ee ldi r24, 0xE8 ; 232
+ e98: 93 e0 ldi r25, 0x03 ; 3
+ e9a: 34 d0 rcall .+104 ; 0xf04 <__divmodhi4>
+ e9c: 6f 50 subi r22, 0x0F ; 15
+ e9e: 70 40 sbci r23, 0x00 ; 0
+ ea0: c6 0f add r28, r22
+ ea2: d7 1f adc r29, r23
+ fill(0x00);
+
+ for (r=0;r<2;r++)
+ {
+ i = 750;
+ while (i>0)
+ ea4: 1c 16 cp r1, r28
+ ea6: 1d 06 cpc r1, r29
+ ea8: 4c f3 brlt .-46 ; 0xe7c <_Z14effect_blinky2v+0x1e>
+ delay_ms(100);
+
+ i = i - (15+(1000/(i/10)));
+ }
+
+ delay_ms(1000);
+ eaa: 88 ee ldi r24, 0xE8 ; 232
+ eac: 93 e0 ldi r25, 0x03 ; 3
+ eae: 03 db rcall .-2554 ; 0x4b6 <_Z8delay_msj>
+ eb0: ce ee ldi r28, 0xEE ; 238
+ eb2: d2 e0 ldi r29, 0x02 ; 2
+
+ i = 750;
+ while (i>0)
+ {
+ fill(0x00);
+ eb4: 80 e0 ldi r24, 0x00 ; 0
+ eb6: e2 da rcall .-2620 ; 0x47c <_Z4fillh>
+ delay_ms(751-i);
+ eb8: c7 01 movw r24, r14
+ eba: 8c 1b sub r24, r28
+ ebc: 9d 0b sbc r25, r29
+ ebe: fb da rcall .-2570 ; 0x4b6 <_Z8delay_msj>
+
+ fill(0xff);
+ ec0: 8f ef ldi r24, 0xFF ; 255
+ ec2: dc da rcall .-2632 ; 0x47c <_Z4fillh>
+ delay_ms(100);
+ ec4: 84 e6 ldi r24, 0x64 ; 100
+ ec6: 90 e0 ldi r25, 0x00 ; 0
+ ec8: f6 da rcall .-2580 ; 0x4b6 <_Z8delay_msj>
+
+ i = i - (15+(1000/(i/10)));
+ eca: ce 01 movw r24, r28
+ ecc: 66 ef ldi r22, 0xF6 ; 246
+ ece: 7f ef ldi r23, 0xFF ; 255
+ ed0: 19 d0 rcall .+50 ; 0xf04 <__divmodhi4>
+ ed2: 88 ee ldi r24, 0xE8 ; 232
+ ed4: 93 e0 ldi r25, 0x03 ; 3
+ ed6: 16 d0 rcall .+44 ; 0xf04 <__divmodhi4>
+ ed8: 6f 50 subi r22, 0x0F ; 15
+ eda: 70 40 sbci r23, 0x00 ; 0
+ edc: c6 0f add r28, r22
+ ede: d7 1f adc r29, r23
+ }
+
+ delay_ms(1000);
+
+ i = 750;
+ while (i>0)
+ ee0: 1c 16 cp r1, r28
+ ee2: 1d 06 cpc r1, r29
+ ee4: 3c f3 brlt .-50 ; 0xeb4 <_Z14effect_blinky2v+0x56>
+void effect_blinky2()
+{
+ int i,r;
+ fill(0x00);
+
+ for (r=0;r<2;r++)
+ ee6: 0f 5f subi r16, 0xFF ; 255
+ ee8: 1f 4f sbci r17, 0xFF ; 255
+ eea: 02 30 cpi r16, 0x02 ; 2
+ eec: 11 05 cpc r17, r1
+ eee: 19 f0 breq .+6 ; 0xef6 <_Z14effect_blinky2v+0x98>
+ ef0: ce ee ldi r28, 0xEE ; 238
+ ef2: d2 e0 ldi r29, 0x02 ; 2
+ ef4: c3 cf rjmp .-122 ; 0xe7c <_Z14effect_blinky2v+0x1e>
+
+ i = i - (15+(1000/(i/10)));
+ }
+ }
+
+}
+ ef6: df 91 pop r29
+ ef8: cf 91 pop r28
+ efa: 1f 91 pop r17
+ efc: 0f 91 pop r16
+ efe: ff 90 pop r15
+ f00: ef 90 pop r14
+ f02: 08 95 ret
+
+00000f04 <__divmodhi4>:
+ f04: 97 fb bst r25, 7
+ f06: 09 2e mov r0, r25
+ f08: 07 26 eor r0, r23
+ f0a: 0a d0 rcall .+20 ; 0xf20 <__divmodhi4_neg1>
+ f0c: 77 fd sbrc r23, 7
+ f0e: 04 d0 rcall .+8 ; 0xf18 <__divmodhi4_neg2>
+ f10: 0c d0 rcall .+24 ; 0xf2a <__udivmodhi4>
+ f12: 06 d0 rcall .+12 ; 0xf20 <__divmodhi4_neg1>
+ f14: 00 20 and r0, r0
+ f16: 1a f4 brpl .+6 ; 0xf1e <__divmodhi4_exit>
+
+00000f18 <__divmodhi4_neg2>:
+ f18: 70 95 com r23
+ f1a: 61 95 neg r22
+ f1c: 7f 4f sbci r23, 0xFF ; 255
+
+00000f1e <__divmodhi4_exit>:
+ f1e: 08 95 ret
+
+00000f20 <__divmodhi4_neg1>:
+ f20: f6 f7 brtc .-4 ; 0xf1e <__divmodhi4_exit>
+ f22: 90 95 com r25
+ f24: 81 95 neg r24
+ f26: 9f 4f sbci r25, 0xFF ; 255
+ f28: 08 95 ret
+
+00000f2a <__udivmodhi4>:
+ f2a: aa 1b sub r26, r26
+ f2c: bb 1b sub r27, r27
+ f2e: 51 e1 ldi r21, 0x11 ; 17
+ f30: 07 c0 rjmp .+14 ; 0xf40 <__udivmodhi4_ep>
+
+00000f32 <__udivmodhi4_loop>:
+ f32: aa 1f adc r26, r26
+ f34: bb 1f adc r27, r27
+ f36: a6 17 cp r26, r22
+ f38: b7 07 cpc r27, r23
+ f3a: 10 f0 brcs .+4 ; 0xf40 <__udivmodhi4_ep>
+ f3c: a6 1b sub r26, r22
+ f3e: b7 0b sbc r27, r23
+
+00000f40 <__udivmodhi4_ep>:
+ f40: 88 1f adc r24, r24
+ f42: 99 1f adc r25, r25
+ f44: 5a 95 dec r21
+ f46: a9 f7 brne .-22 ; 0xf32 <__udivmodhi4_loop>
+ f48: 80 95 com r24
+ f4a: 90 95 com r25
+ f4c: bc 01 movw r22, r24
+ f4e: cd 01 movw r24, r26
+ f50: 08 95 ret
+
+00000f52 <__prologue_saves__>:
+ f52: 2f 92 push r2
+ f54: 3f 92 push r3
+ f56: 4f 92 push r4
+ f58: 5f 92 push r5
+ f5a: 6f 92 push r6
+ f5c: 7f 92 push r7
+ f5e: 8f 92 push r8
+ f60: 9f 92 push r9
+ f62: af 92 push r10
+ f64: bf 92 push r11
+ f66: cf 92 push r12
+ f68: df 92 push r13
+ f6a: ef 92 push r14
+ f6c: ff 92 push r15
+ f6e: 0f 93 push r16
+ f70: 1f 93 push r17
+ f72: cf 93 push r28
+ f74: df 93 push r29
+ f76: cd b7 in r28, 0x3d ; 61
+ f78: de b7 in r29, 0x3e ; 62
+ f7a: ca 1b sub r28, r26
+ f7c: db 0b sbc r29, r27
+ f7e: 0f b6 in r0, 0x3f ; 63
+ f80: f8 94 cli
+ f82: de bf out 0x3e, r29 ; 62
+ f84: 0f be out 0x3f, r0 ; 63
+ f86: cd bf out 0x3d, r28 ; 61
+ f88: 09 94 ijmp
+
+00000f8a <__epilogue_restores__>:
+ f8a: 2a 88 ldd r2, Y+18 ; 0x12
+ f8c: 39 88 ldd r3, Y+17 ; 0x11
+ f8e: 48 88 ldd r4, Y+16 ; 0x10
+ f90: 5f 84 ldd r5, Y+15 ; 0x0f
+ f92: 6e 84 ldd r6, Y+14 ; 0x0e
+ f94: 7d 84 ldd r7, Y+13 ; 0x0d
+ f96: 8c 84 ldd r8, Y+12 ; 0x0c
+ f98: 9b 84 ldd r9, Y+11 ; 0x0b
+ f9a: aa 84 ldd r10, Y+10 ; 0x0a
+ f9c: b9 84 ldd r11, Y+9 ; 0x09
+ f9e: c8 84 ldd r12, Y+8 ; 0x08
+ fa0: df 80 ldd r13, Y+7 ; 0x07
+ fa2: ee 80 ldd r14, Y+6 ; 0x06
+ fa4: fd 80 ldd r15, Y+5 ; 0x05
+ fa6: 0c 81 ldd r16, Y+4 ; 0x04
+ fa8: 1b 81 ldd r17, Y+3 ; 0x03
+ faa: aa 81 ldd r26, Y+2 ; 0x02
+ fac: b9 81 ldd r27, Y+1 ; 0x01
+ fae: ce 0f add r28, r30
+ fb0: d1 1d adc r29, r1
+ fb2: 0f b6 in r0, 0x3f ; 63
+ fb4: f8 94 cli
+ fb6: de bf out 0x3e, r29 ; 62
+ fb8: 0f be out 0x3f, r0 ; 63
+ fba: cd bf out 0x3d, r28 ; 61
+ fbc: ed 01 movw r28, r26
+ fbe: 08 95 ret
+
+00000fc0 <do_rand>:
+ fc0: a0 e0 ldi r26, 0x00 ; 0
+ fc2: b0 e0 ldi r27, 0x00 ; 0
+ fc4: e5 ee ldi r30, 0xE5 ; 229
+ fc6: f7 e0 ldi r31, 0x07 ; 7
+ fc8: cc cf rjmp .-104 ; 0xf62 <__prologue_saves__+0x10>
+ fca: ec 01 movw r28, r24
+ fcc: a8 80 ld r10, Y
+ fce: b9 80 ldd r11, Y+1 ; 0x01
+ fd0: ca 80 ldd r12, Y+2 ; 0x02
+ fd2: db 80 ldd r13, Y+3 ; 0x03
+ fd4: a1 14 cp r10, r1
+ fd6: b1 04 cpc r11, r1
+ fd8: c1 04 cpc r12, r1
+ fda: d1 04 cpc r13, r1
+ fdc: 41 f4 brne .+16 ; 0xfee <do_rand+0x2e>
+ fde: 84 e2 ldi r24, 0x24 ; 36
+ fe0: a8 2e mov r10, r24
+ fe2: 89 ed ldi r24, 0xD9 ; 217
+ fe4: b8 2e mov r11, r24
+ fe6: 8b e5 ldi r24, 0x5B ; 91
+ fe8: c8 2e mov r12, r24
+ fea: 87 e0 ldi r24, 0x07 ; 7
+ fec: d8 2e mov r13, r24
+ fee: c6 01 movw r24, r12
+ ff0: b5 01 movw r22, r10
+ ff2: 2d e1 ldi r18, 0x1D ; 29
+ ff4: 33 ef ldi r19, 0xF3 ; 243
+ ff6: 41 e0 ldi r20, 0x01 ; 1
+ ff8: 50 e0 ldi r21, 0x00 ; 0
+ ffa: 5a d0 rcall .+180 ; 0x10b0 <__divmodsi4>
+ ffc: 27 ea ldi r18, 0xA7 ; 167
+ ffe: 31 e4 ldi r19, 0x41 ; 65
+ 1000: 40 e0 ldi r20, 0x00 ; 0
+ 1002: 50 e0 ldi r21, 0x00 ; 0
+ 1004: 36 d0 rcall .+108 ; 0x1072 <__mulsi3>
+ 1006: 7b 01 movw r14, r22
+ 1008: 8c 01 movw r16, r24
+ 100a: c6 01 movw r24, r12
+ 100c: b5 01 movw r22, r10
+ 100e: 2d e1 ldi r18, 0x1D ; 29
+ 1010: 33 ef ldi r19, 0xF3 ; 243
+ 1012: 41 e0 ldi r20, 0x01 ; 1
+ 1014: 50 e0 ldi r21, 0x00 ; 0
+ 1016: 4c d0 rcall .+152 ; 0x10b0 <__divmodsi4>
+ 1018: ca 01 movw r24, r20
+ 101a: b9 01 movw r22, r18
+ 101c: 2c ee ldi r18, 0xEC ; 236
+ 101e: 34 ef ldi r19, 0xF4 ; 244
+ 1020: 4f ef ldi r20, 0xFF ; 255
+ 1022: 5f ef ldi r21, 0xFF ; 255
+ 1024: 26 d0 rcall .+76 ; 0x1072 <__mulsi3>
+ 1026: 6e 0d add r22, r14
+ 1028: 7f 1d adc r23, r15
+ 102a: 80 1f adc r24, r16
+ 102c: 91 1f adc r25, r17
+ 102e: 97 ff sbrs r25, 7
+ 1030: 04 c0 rjmp .+8 ; 0x103a <do_rand+0x7a>
+ 1032: 61 50 subi r22, 0x01 ; 1
+ 1034: 70 40 sbci r23, 0x00 ; 0
+ 1036: 80 40 sbci r24, 0x00 ; 0
+ 1038: 90 48 sbci r25, 0x80 ; 128
+ 103a: 68 83 st Y, r22
+ 103c: 79 83 std Y+1, r23 ; 0x01
+ 103e: 8a 83 std Y+2, r24 ; 0x02
+ 1040: 9b 83 std Y+3, r25 ; 0x03
+ 1042: 9b 01 movw r18, r22
+ 1044: 3f 77 andi r19, 0x7F ; 127
+ 1046: c9 01 movw r24, r18
+ 1048: cd b7 in r28, 0x3d ; 61
+ 104a: de b7 in r29, 0x3e ; 62
+ 104c: ea e0 ldi r30, 0x0A ; 10
+ 104e: a5 cf rjmp .-182 ; 0xf9a <__epilogue_restores__+0x10>
+
+00001050 <rand_r>:
+ 1050: b7 df rcall .-146 ; 0xfc0 <do_rand>
+ 1052: 08 95 ret
+
+00001054 <rand>:
+ 1054: 80 e6 ldi r24, 0x60 ; 96
+ 1056: 90 e0 ldi r25, 0x00 ; 0
+ 1058: b3 df rcall .-154 ; 0xfc0 <do_rand>
+ 105a: 08 95 ret
+
+0000105c <srand>:
+ 105c: a0 e0 ldi r26, 0x00 ; 0
+ 105e: b0 e0 ldi r27, 0x00 ; 0
+ 1060: 80 93 60 00 sts 0x0060, r24
+ 1064: 90 93 61 00 sts 0x0061, r25
+ 1068: a0 93 62 00 sts 0x0062, r26
+ 106c: b0 93 63 00 sts 0x0063, r27
+ 1070: 08 95 ret
+
+00001072 <__mulsi3>:
+ 1072: 62 9f mul r22, r18
+ 1074: d0 01 movw r26, r0
+ 1076: 73 9f mul r23, r19
+ 1078: f0 01 movw r30, r0
+ 107a: 82 9f mul r24, r18
+ 107c: e0 0d add r30, r0
+ 107e: f1 1d adc r31, r1
+ 1080: 64 9f mul r22, r20
+ 1082: e0 0d add r30, r0
+ 1084: f1 1d adc r31, r1
+ 1086: 92 9f mul r25, r18
+ 1088: f0 0d add r31, r0
+ 108a: 83 9f mul r24, r19
+ 108c: f0 0d add r31, r0
+ 108e: 74 9f mul r23, r20
+ 1090: f0 0d add r31, r0
+ 1092: 65 9f mul r22, r21
+ 1094: f0 0d add r31, r0
+ 1096: 99 27 eor r25, r25
+ 1098: 72 9f mul r23, r18
+ 109a: b0 0d add r27, r0
+ 109c: e1 1d adc r30, r1
+ 109e: f9 1f adc r31, r25
+ 10a0: 63 9f mul r22, r19
+ 10a2: b0 0d add r27, r0
+ 10a4: e1 1d adc r30, r1
+ 10a6: f9 1f adc r31, r25
+ 10a8: bd 01 movw r22, r26
+ 10aa: cf 01 movw r24, r30
+ 10ac: 11 24 eor r1, r1
+ 10ae: 08 95 ret
+
+000010b0 <__divmodsi4>:
+ 10b0: 97 fb bst r25, 7
+ 10b2: 09 2e mov r0, r25
+ 10b4: 05 26 eor r0, r21
+ 10b6: 0e d0 rcall .+28 ; 0x10d4 <__divmodsi4_neg1>
+ 10b8: 57 fd sbrc r21, 7
+ 10ba: 04 d0 rcall .+8 ; 0x10c4 <__divmodsi4_neg2>
+ 10bc: 14 d0 rcall .+40 ; 0x10e6 <__udivmodsi4>
+ 10be: 0a d0 rcall .+20 ; 0x10d4 <__divmodsi4_neg1>
+ 10c0: 00 1c adc r0, r0
+ 10c2: 38 f4 brcc .+14 ; 0x10d2 <__divmodsi4_exit>
+
+000010c4 <__divmodsi4_neg2>:
+ 10c4: 50 95 com r21
+ 10c6: 40 95 com r20
+ 10c8: 30 95 com r19
+ 10ca: 21 95 neg r18
+ 10cc: 3f 4f sbci r19, 0xFF ; 255
+ 10ce: 4f 4f sbci r20, 0xFF ; 255
+ 10d0: 5f 4f sbci r21, 0xFF ; 255
+
+000010d2 <__divmodsi4_exit>:
+ 10d2: 08 95 ret
+
+000010d4 <__divmodsi4_neg1>:
+ 10d4: f6 f7 brtc .-4 ; 0x10d2 <__divmodsi4_exit>
+ 10d6: 90 95 com r25
+ 10d8: 80 95 com r24
+ 10da: 70 95 com r23
+ 10dc: 61 95 neg r22
+ 10de: 7f 4f sbci r23, 0xFF ; 255
+ 10e0: 8f 4f sbci r24, 0xFF ; 255
+ 10e2: 9f 4f sbci r25, 0xFF ; 255
+ 10e4: 08 95 ret
+
+000010e6 <__udivmodsi4>:
+ 10e6: a1 e2 ldi r26, 0x21 ; 33
+ 10e8: 1a 2e mov r1, r26
+ 10ea: aa 1b sub r26, r26
+ 10ec: bb 1b sub r27, r27
+ 10ee: fd 01 movw r30, r26
+ 10f0: 0d c0 rjmp .+26 ; 0x110c <__udivmodsi4_ep>
+
+000010f2 <__udivmodsi4_loop>:
+ 10f2: aa 1f adc r26, r26
+ 10f4: bb 1f adc r27, r27
+ 10f6: ee 1f adc r30, r30
+ 10f8: ff 1f adc r31, r31
+ 10fa: a2 17 cp r26, r18
+ 10fc: b3 07 cpc r27, r19
+ 10fe: e4 07 cpc r30, r20
+ 1100: f5 07 cpc r31, r21
+ 1102: 20 f0 brcs .+8 ; 0x110c <__udivmodsi4_ep>
+ 1104: a2 1b sub r26, r18
+ 1106: b3 0b sbc r27, r19
+ 1108: e4 0b sbc r30, r20
+ 110a: f5 0b sbc r31, r21
+
+0000110c <__udivmodsi4_ep>:
+ 110c: 66 1f adc r22, r22
+ 110e: 77 1f adc r23, r23
+ 1110: 88 1f adc r24, r24
+ 1112: 99 1f adc r25, r25
+ 1114: 1a 94 dec r1
+ 1116: 69 f7 brne .-38 ; 0x10f2 <__udivmodsi4_loop>
+ 1118: 60 95 com r22
+ 111a: 70 95 com r23
+ 111c: 80 95 com r24
+ 111e: 90 95 com r25
+ 1120: 9b 01 movw r18, r22
+ 1122: ac 01 movw r20, r24
+ 1124: bd 01 movw r22, r26
+ 1126: cf 01 movw r24, r30
+ 1128: 08 95 ret
+
+0000112a <_exit>:
+ 112a: f8 94 cli
+
+0000112c <__stop_program>:
+ 112c: ff cf rjmp .-2 ; 0x112c <__stop_program>
diff --git a/avr-test/ledcube.map b/avr-test/ledcube.map
new file mode 100644
index 0000000..eaa732b
--- /dev/null
+++ b/avr-test/ledcube.map
@@ -0,0 +1,783 @@
+Archive member included because of file (symbol)
+
+/usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_divmodhi4.o)
+ effect.o (__divmodhi4)
+/usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_exit.o)
+ /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/crtm8.o (exit)
+/usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_clear_bss.o)
+ main.o (__do_clear_bss)
+/usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_fixunssfsi.o)
+ draw.o (__fixunssfsi)
+/usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_addsub_sf.o)
+ /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_fixunssfsi.o) (__subsf3)
+/usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_mul_sf.o)
+ draw.o (__mulsf3)
+/usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_div_sf.o)
+ draw.o (__divsf3)
+/usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_ge_sf.o)
+ /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_fixunssfsi.o) (__gesf2)
+/usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_si_to_sf.o)
+ draw.o (__floatsisf)
+/usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_sf_to_si.o)
+ effect.o (__fixsfsi)
+/usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_thenan_sf.o)
+ /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_addsub_sf.o) (__thenan_sf)
+/usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_udivmodhi4.o)
+ /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_divmodhi4.o) (__udivmodhi4)
+/usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_prologue.o)
+ /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_addsub_sf.o) (__prologue_saves__)
+/usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_epilogue.o)
+ /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_addsub_sf.o) (__epilogue_restores__)
+/usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_copy_data.o)
+ /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_thenan_sf.o) (__do_copy_data)
+/usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_clzsi2.o)
+ /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_si_to_sf.o) (__clzsi2)
+/usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_pack_sf.o)
+ /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_addsub_sf.o) (__pack_f)
+/usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_unpack_sf.o)
+ /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_addsub_sf.o) (__unpack_f)
+/usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_fpcmp_parts_sf.o)
+ /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_ge_sf.o) (__fpcmp_parts_f)
+/usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_clz.o)
+ /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_clzsi2.o) (__clz_tab)
+/usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(cos.o)
+ effect.o (cos)
+/usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_rempio2.o)
+ /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(cos.o) (__fp_rempio2)
+/usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_sinus.o)
+ /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(cos.o) (__fp_sinus)
+/usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_split3.o)
+ /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_rempio2.o) (__fp_splitA)
+/usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(sin.o)
+ effect.o (sin)
+/usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(addsf3x.o)
+ /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_sinus.o) (__addsf3x)
+/usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_inf.o)
+ /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(addsf3x.o) (__fp_inf)
+/usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_mpack.o)
+ /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_rempio2.o) (__fp_mpack_finite)
+/usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_nan.o)
+ /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_rempio2.o) (__fp_nan)
+/usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_powsodd.o)
+ /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_sinus.o) (__fp_powsodd)
+/usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_pscA.o)
+ /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(addsf3x.o) (__fp_pscA)
+/usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_pscB.o)
+ /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(addsf3x.o) (__fp_pscB)
+/usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_round.o)
+ /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_sinus.o) (__fp_round)
+/usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_zero.o)
+ /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(addsf3x.o) (__fp_zero)
+/usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_powser.o)
+ /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_powsodd.o) (__fp_powser)
+/usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(mulsf3x.o)
+ /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_powser.o) (__mulsf3x)
+/usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libc.a(rand.o)
+ main.o (rand)
+/usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_mulsi3.o)
+ /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libc.a(rand.o) (__mulsi3)
+/usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_divmodsi4.o)
+ /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libc.a(rand.o) (__divmodsi4)
+/usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_udivmodsi4.o)
+ /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_divmodsi4.o) (__udivmodsi4)
+
+Discarded input sections
+
+ .data 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/crtm8.o
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/crtm8.o
+ .text 0x00000000 0x0 main.o
+ .data 0x00000000 0x0 main.o
+ .text._Z5delaym
+ 0x00000000 0x52 main.o
+ .text._Z9clear_ledv
+ 0x00000000 0x36 main.o
+ .text 0x00000000 0x0 draw.o
+ .data 0x00000000 0x0 draw.o
+ .bss 0x00000000 0x0 draw.o
+ .text._Z11tmpclrvoxeliii
+ 0x00000000 0x4c draw.o
+ .text._Z11tmpsetvoxeliii
+ 0x00000000 0x4a draw.o
+ .text._Z8flpvoxeliii
+ 0x00000000 0x4a draw.o
+ .text._Z8argorderiiPiS_
+ 0x00000000 0x24 draw.o
+ .text._Z10setplane_zi
+ 0x00000000 0x2e draw.o
+ .text._Z10clrplane_zi
+ 0x00000000 0x2c draw.o
+ .text._Z10setplane_xi
+ 0x00000000 0x56 draw.o
+ .text._Z10clrplane_xi
+ 0x00000000 0x58 draw.o
+ .text._Z10setplane_yi
+ 0x00000000 0x2e draw.o
+ .text._Z10clrplane_yi
+ 0x00000000 0x2c draw.o
+ .text._Z8setplanech
+ 0x00000000 0x74 draw.o
+ .text._Z8clrplanech
+ 0x00000000 0x70 draw.o
+ .text._Z7tmpfillh
+ 0x00000000 0x3a draw.o
+ .text._Z10box_fillediiiiii
+ 0x00000000 0x96 draw.o
+ .text._Z9box_wallsiiiiii
+ 0x00000000 0xe8 draw.o
+ .text._Z13box_wireframeiiiiii
+ 0x00000000 0x12e draw.o
+ .text._Z8bytelineii
+ 0x00000000 0x28 draw.o
+ .text._Z8flipbytec
+ 0x00000000 0x70 draw.o
+ .text._Z4lineiiiiii
+ 0x00000000 0x1da draw.o
+ .text._Z8mirror_zv
+ 0x00000000 0x84 draw.o
+ .text._Z8mirror_xv
+ 0x00000000 0xba draw.o
+ .text._Z8mirror_yv
+ 0x00000000 0xde draw.o
+ .text._Z8tmp2cubev
+ 0x00000000 0x14 draw.o
+ .text 0x00000000 0x0 effect.o
+ .data 0x00000000 0x0 effect.o
+ .bss 0x00000000 0x0 effect.o
+ .text._Z15effect_pathmovePhi
+ 0x00000000 0xa6 effect.o
+ .text._Z20effect_telcstairs_doiii
+ 0x00000000 0x48 effect.o
+ .text._Z17effect_telcstairsiii
+ 0x00000000 0x3e effect.o
+ .text._Z27effect_random_sparkle_flashiii
+ 0x00000000 0x98 effect.o
+ .text._Z21effect_random_sparklev
+ 0x00000000 0x32 effect.o
+ .text._Z14effect_loadbari
+ 0x00000000 0xa6 effect.o
+ .text._Z30effect_axis_updown_randsuspendciii
+ 0x00000000 0x15c effect.o
+ .text._Z10boingboingjihh
+ 0x00000000 0x538 effect.o
+ .text._Z16sendplane_rand_zhii
+ 0x00000000 0x6c effect.o
+ .text._Z19effect_box_woopwoopii
+ 0x00000000 0x7a effect.o
+ .text._Z22effect_box_shrink_growiiij
+ 0x00000000 0x100 effect.o
+ .text._Z16effect_planboingii
+ 0x00000000 0x46 effect.o
+ .text._Z11effect_testv
+ 0x00000000 0xa4 effect.o
+ .text 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_divmodhi4.o)
+ .data 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_divmodhi4.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_divmodhi4.o)
+ .text 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_exit.o)
+ .data 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_exit.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_exit.o)
+ .text.libgcc 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_exit.o)
+ .text 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_clear_bss.o)
+ .data 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_clear_bss.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_clear_bss.o)
+ .text.libgcc 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_clear_bss.o)
+ .text 0x00000000 0x50 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_fixunssfsi.o)
+ .data 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_fixunssfsi.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_fixunssfsi.o)
+ .text 0x00000000 0x338 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_addsub_sf.o)
+ .data 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_addsub_sf.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_addsub_sf.o)
+ .text 0x00000000 0x1ea /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_mul_sf.o)
+ .data 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_mul_sf.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_mul_sf.o)
+ .text 0x00000000 0x14e /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_div_sf.o)
+ .data 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_div_sf.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_div_sf.o)
+ .text 0x00000000 0x56 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_ge_sf.o)
+ .data 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_ge_sf.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_ge_sf.o)
+ .text 0x00000000 0xb4 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_si_to_sf.o)
+ .data 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_si_to_sf.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_si_to_sf.o)
+ .text 0x00000000 0xa2 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_sf_to_si.o)
+ .data 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_sf_to_si.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_sf_to_si.o)
+ .text 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_thenan_sf.o)
+ .data 0x00000000 0x8 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_thenan_sf.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_thenan_sf.o)
+ .text 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_udivmodhi4.o)
+ .data 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_udivmodhi4.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_udivmodhi4.o)
+ .text 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_prologue.o)
+ .data 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_prologue.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_prologue.o)
+ .text 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_epilogue.o)
+ .data 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_epilogue.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_epilogue.o)
+ .text 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_copy_data.o)
+ .data 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_copy_data.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_copy_data.o)
+ .text.libgcc 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_copy_data.o)
+ .text 0x00000000 0x9e /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_clzsi2.o)
+ .data 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_clzsi2.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_clzsi2.o)
+ .text 0x00000000 0x1aa /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_pack_sf.o)
+ .data 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_pack_sf.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_pack_sf.o)
+ .text 0x00000000 0xf0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_unpack_sf.o)
+ .data 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_unpack_sf.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_unpack_sf.o)
+ .text 0x00000000 0xb2 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_fpcmp_parts_sf.o)
+ .data 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_fpcmp_parts_sf.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_fpcmp_parts_sf.o)
+ .text 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_clz.o)
+ .data 0x00000000 0x100 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_clz.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_clz.o)
+ .text 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(cos.o)
+ .data 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(cos.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(cos.o)
+ .text.avr-libc.fplib
+ 0x00000000 0x6 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(cos.o)
+ .text 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_rempio2.o)
+ .data 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_rempio2.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_rempio2.o)
+ .text.avr-libc.fplib
+ 0x00000000 0x50 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_rempio2.o)
+ .text 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_sinus.o)
+ .data 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_sinus.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_sinus.o)
+ .text.avr-libc.fplib
+ 0x00000000 0x22 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_sinus.o)
+ .progmem.gcc_fplib
+ 0x00000000 0x1e /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_sinus.o)
+ .text 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_split3.o)
+ .data 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_split3.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_split3.o)
+ .text.avr-libc.fplib
+ 0x00000000 0x44 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_split3.o)
+ .text 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(sin.o)
+ .data 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(sin.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(sin.o)
+ .text.avr-libc.fplib
+ 0x00000000 0xc /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(sin.o)
+ .text 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(addsf3x.o)
+ .data 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(addsf3x.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(addsf3x.o)
+ .text.avr-libc.fplib
+ 0x00000000 0xc0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(addsf3x.o)
+ .text 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_inf.o)
+ .data 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_inf.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_inf.o)
+ .text.avr-libc.fplib
+ 0x00000000 0xc /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_inf.o)
+ .text 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_mpack.o)
+ .data 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_mpack.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_mpack.o)
+ .text.avr-libc.fplib
+ 0x00000000 0x1c /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_mpack.o)
+ .text 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_nan.o)
+ .data 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_nan.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_nan.o)
+ .text.avr-libc.fplib
+ 0x00000000 0x6 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_nan.o)
+ .text 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_powsodd.o)
+ .data 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_powsodd.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_powsodd.o)
+ .text.avr-libc.fplib
+ 0x00000000 0x22 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_powsodd.o)
+ .text 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_pscA.o)
+ .data 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_pscA.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_pscA.o)
+ .text.avr-libc.fplib
+ 0x00000000 0xe /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_pscA.o)
+ .text 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_pscB.o)
+ .data 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_pscB.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_pscB.o)
+ .text.avr-libc.fplib
+ 0x00000000 0xe /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_pscB.o)
+ .text 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_round.o)
+ .data 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_round.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_round.o)
+ .text.avr-libc.fplib
+ 0x00000000 0x22 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_round.o)
+ .text 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_zero.o)
+ .data 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_zero.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_zero.o)
+ .text.avr-libc.fplib
+ 0x00000000 0xe /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_zero.o)
+ .text 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_powser.o)
+ .data 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_powser.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_powser.o)
+ .text.avr-libc.fplib
+ 0x00000000 0x4a /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_powser.o)
+ .text 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(mulsf3x.o)
+ .data 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(mulsf3x.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(mulsf3x.o)
+ .text.avr-libc.fplib
+ 0x00000000 0xc2 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(mulsf3x.o)
+ .text 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libc.a(rand.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libc.a(rand.o)
+ .text 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_mulsi3.o)
+ .data 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_mulsi3.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_mulsi3.o)
+ .text 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_divmodsi4.o)
+ .data 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_divmodsi4.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_divmodsi4.o)
+ .text 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_udivmodsi4.o)
+ .data 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_udivmodsi4.o)
+ .bss 0x00000000 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_udivmodsi4.o)
+
+Memory Configuration
+
+Name Origin Length Attributes
+text 0x00000000 0x00002000 xr
+data 0x00800060 0x0000ffa0 rw !x
+eeprom 0x00810000 0x00010000 rw !x
+fuse 0x00820000 0x00000400 rw !x
+lock 0x00830000 0x00000400 rw !x
+signature 0x00840000 0x00000400 rw !x
+*default* 0x00000000 0xffffffff
+
+Linker script and memory map
+
+LOAD /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/crtm8.o
+LOAD main.o
+LOAD draw.o
+LOAD effect.o
+LOAD /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a
+LOAD /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a
+LOAD /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a
+LOAD /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libc.a
+LOAD /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a
+
+.hash
+ *(.hash)
+
+.dynsym
+ *(.dynsym)
+
+.dynstr
+ *(.dynstr)
+
+.gnu.version
+ *(.gnu.version)
+
+.gnu.version_d
+ *(.gnu.version_d)
+
+.gnu.version_r
+ *(.gnu.version_r)
+
+.rel.init
+ *(.rel.init)
+
+.rela.init
+ *(.rela.init)
+
+.rel.text
+ *(.rel.text)
+ *(.rel.text.*)
+ *(.rel.gnu.linkonce.t*)
+
+.rela.text
+ *(.rela.text)
+ *(.rela.text.*)
+ *(.rela.gnu.linkonce.t*)
+
+.rel.fini
+ *(.rel.fini)
+
+.rela.fini
+ *(.rela.fini)
+
+.rel.rodata
+ *(.rel.rodata)
+ *(.rel.rodata.*)
+ *(.rel.gnu.linkonce.r*)
+
+.rela.rodata
+ *(.rela.rodata)
+ *(.rela.rodata.*)
+ *(.rela.gnu.linkonce.r*)
+
+.rel.data
+ *(.rel.data)
+ *(.rel.data.*)
+ *(.rel.gnu.linkonce.d*)
+
+.rela.data
+ *(.rela.data)
+ *(.rela.data.*)
+ *(.rela.gnu.linkonce.d*)
+
+.rel.ctors
+ *(.rel.ctors)
+
+.rela.ctors
+ *(.rela.ctors)
+
+.rel.dtors
+ *(.rel.dtors)
+
+.rela.dtors
+ *(.rela.dtors)
+
+.rel.got
+ *(.rel.got)
+
+.rela.got
+ *(.rela.got)
+
+.rel.bss
+ *(.rel.bss)
+
+.rela.bss
+ *(.rela.bss)
+
+.rel.plt
+ *(.rel.plt)
+
+.rela.plt
+ *(.rela.plt)
+
+.text 0x00000000 0x112e
+ *(.vectors)
+ .vectors 0x00000000 0x26 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/crtm8.o
+ 0x00000000 __vectors
+ 0x00000000 __vector_default
+ *(.vectors)
+ *(.progmem.gcc*)
+ *(.progmem*)
+ 0x00000026 . = ALIGN (0x2)
+ 0x00000026 __trampolines_start = .
+ *(.trampolines)
+ .trampolines 0x00000026 0x0 linker stubs
+ *(.trampolines*)
+ 0x00000026 __trampolines_end = .
+ *(.jumptables)
+ *(.jumptables*)
+ *(.lowtext)
+ *(.lowtext*)
+ 0x00000026 __ctors_start = .
+ *(.ctors)
+ 0x00000026 __ctors_end = .
+ 0x00000026 __dtors_start = .
+ *(.dtors)
+ 0x00000026 __dtors_end = .
+ SORT(*)(.ctors)
+ SORT(*)(.dtors)
+ *(.init0)
+ .init0 0x00000026 0x0 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/crtm8.o
+ 0x00000026 __init
+ *(.init0)
+ *(.init1)
+ *(.init1)
+ *(.init2)
+ .init2 0x00000026 0xc /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/crtm8.o
+ *(.init2)
+ *(.init3)
+ *(.init3)
+ *(.init4)
+ .init4 0x00000032 0x10 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_clear_bss.o)
+ 0x00000032 __do_clear_bss
+ .init4 0x00000042 0x16 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_copy_data.o)
+ 0x00000042 __do_copy_data
+ *(.init4)
+ *(.init5)
+ *(.init5)
+ *(.init6)
+ *(.init6)
+ *(.init7)
+ *(.init7)
+ *(.init8)
+ *(.init8)
+ *(.init9)
+ .init9 0x00000058 0x4 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/crtm8.o
+ *(.init9)
+ *(.text)
+ .text 0x0000005c 0x2 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/crtm8.o
+ 0x0000005c __vector_1
+ 0x0000005c __vector_12
+ 0x0000005c __bad_interrupt
+ 0x0000005c __vector_6
+ 0x0000005c __vector_11
+ 0x0000005c __vector_13
+ 0x0000005c __vector_17
+ 0x0000005c __vector_7
+ 0x0000005c __vector_5
+ 0x0000005c __vector_4
+ 0x0000005c __vector_2
+ 0x0000005c __vector_15
+ 0x0000005c __vector_8
+ 0x0000005c __vector_14
+ 0x0000005c __vector_10
+ 0x0000005c __vector_16
+ 0x0000005c __vector_18
+ 0x0000005e . = ALIGN (0x2)
+ *(.text.*)
+ .text.__vector_9
+ 0x0000005e 0x8a main.o
+ 0x0000005e __vector_9
+ .text.__vector_3
+ 0x000000e8 0x124 main.o
+ 0x000000e8 __vector_3
+ .text.main 0x0000020c 0x15c main.o
+ 0x0000020c main
+ .text._Z6myrandv
+ 0x00000368 0x4 main.o
+ 0x00000368 myrand()
+ .text._Z7inrangeiii
+ 0x0000036c 0x28 draw.o
+ 0x0000036c inrange(int, int, int)
+ .text._Z8clrvoxeliii
+ 0x00000394 0x4c draw.o
+ 0x00000394 clrvoxel(int, int, int)
+ .text._Z8setvoxeliii
+ 0x000003e0 0x4a draw.o
+ 0x000003e0 setvoxel(int, int, int)
+ .text._Z8getvoxeliii
+ 0x0000042a 0x44 draw.o
+ 0x0000042a getvoxel(int, int, int)
+ .text._Z10altervoxeliiii
+ 0x0000046e 0xe draw.o
+ 0x0000046e altervoxel(int, int, int, int)
+ .text._Z4fillh
+ 0x0000047c 0x3a draw.o
+ 0x0000047c fill(unsigned char)
+ .text._Z8delay_msj
+ 0x000004b6 0x1e draw.o
+ 0x000004b6 delay_ms(unsigned int)
+ .text._Z5shiftci
+ 0x000004d4 0x15e draw.o
+ 0x000004d4 shift(char, int)
+ .text._Z18effect_wormsqueezeiiiii
+ 0x00000632 0x1a6 effect.o
+ 0x00000632 effect_wormsqueeze(int, int, int, int, int)
+ .text._Z11effect_raini
+ 0x000007d8 0x8c effect.o
+ 0x000007d8 effect_rain(int)
+ .text._Z11sendvoxel_zhhhi
+ 0x00000864 0x96 effect.o
+ 0x00000864 sendvoxel_z(unsigned char, unsigned char, unsigned char, int)
+ .text._Z19draw_positions_axiscPhi
+ 0x000008fa 0xd0 effect.o
+ 0x000008fa draw_positions_axis(char, unsigned char*, int)
+ .text._Z32effect_boxside_randsend_parallelciii
+ 0x000009ca 0x16c effect.o
+ 0x000009ca effect_boxside_randsend_parallel(char, int, int, int)
+ .text._Z20effect_z_updown_movePhS_c
+ 0x00000b36 0x3c effect.o
+ 0x00000b36 effect_z_updown_move(unsigned char*, unsigned char*, char)
+ .text._Z15effect_z_updownii
+ 0x00000b72 0x156 effect.o
+ 0x00000b72 effect_z_updown(int, int)
+ .text._Z20effect_random_fillerii
+ 0x00000cc8 0xbc effect.o
+ 0x00000cc8 effect_random_filler(int, int)
+ .text._Z17sendvoxels_rand_ziii
+ 0x00000d84 0xda effect.o
+ 0x00000d84 sendvoxels_rand_z(int, int, int)
+ .text._Z14effect_blinky2v
+ 0x00000e5e 0xa6 effect.o
+ 0x00000e5e effect_blinky2()
+ .text.libgcc 0x00000f04 0x26 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_divmodhi4.o)
+ 0x00000f04 __divmodhi4
+ 0x00000f04 _div
+ .text.libgcc 0x00000f2a 0x28 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_udivmodhi4.o)
+ 0x00000f2a __udivmodhi4
+ .text.libgcc 0x00000f52 0x38 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_prologue.o)
+ 0x00000f52 __prologue_saves__
+ .text.libgcc 0x00000f8a 0x36 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_epilogue.o)
+ 0x00000f8a __epilogue_restores__
+ .text.avr-libc
+ 0x00000fc0 0xb2 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libc.a(rand.o)
+ 0x00001050 rand_r
+ 0x00001054 rand
+ 0x0000105c srand
+ .text.libgcc 0x00001072 0x3e /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_mulsi3.o)
+ 0x00001072 __mulsi3
+ .text.libgcc 0x000010b0 0x36 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_divmodsi4.o)
+ 0x000010b0 __divmodsi4
+ .text.libgcc 0x000010e6 0x44 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_udivmodsi4.o)
+ 0x000010e6 __udivmodsi4
+ 0x0000112a . = ALIGN (0x2)
+ *(.fini9)
+ .fini9 0x0000112a 0x0 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_exit.o)
+ 0x0000112a exit
+ 0x0000112a _exit
+ *(.fini9)
+ *(.fini8)
+ *(.fini8)
+ *(.fini7)
+ *(.fini7)
+ *(.fini6)
+ *(.fini6)
+ *(.fini5)
+ *(.fini5)
+ *(.fini4)
+ *(.fini4)
+ *(.fini3)
+ *(.fini3)
+ *(.fini2)
+ *(.fini2)
+ *(.fini1)
+ *(.fini1)
+ *(.fini0)
+ .fini0 0x0000112a 0x4 /usr/lib/gcc/avr/4.3.5/avr4/libgcc.a(_exit.o)
+ *(.fini0)
+ 0x0000112e _etext = .
+
+.data 0x00800060 0x4 load address 0x0000112e
+ 0x00800060 PROVIDE (__data_start, .)
+ *(.data)
+ .data 0x00800060 0x4 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libc.a(rand.o)
+ *(.data*)
+ *(.rodata)
+ *(.rodata*)
+ *(.gnu.linkonce.d*)
+ 0x00800064 . = ALIGN (0x2)
+ 0x00800064 _edata = .
+ 0x00800064 PROVIDE (__data_end, .)
+
+.bss 0x00800064 0x88
+ 0x00800064 PROVIDE (__bss_start, .)
+ *(.bss)
+ .bss 0x00800064 0x88 main.o
+ 0x00800064 cube
+ 0x008000a4 in_wait
+ 0x008000a5 fb
+ 0x008000e5 timer0_millis
+ 0x008000e9 current_layer
+ 0x008000ea pgm_mode
+ *(.bss*)
+ *(COMMON)
+ 0x008000ec PROVIDE (__bss_end, .)
+ 0x0000112e __data_load_start = LOADADDR (.data)
+ 0x00001132 __data_load_end = (__data_load_start + SIZEOF (.data))
+
+.noinit 0x008000ec 0x0
+ 0x008000ec PROVIDE (__noinit_start, .)
+ *(.noinit*)
+ 0x008000ec PROVIDE (__noinit_end, .)
+ 0x008000ec _end = .
+ 0x008000ec PROVIDE (__heap_start, .)
+
+.eeprom 0x00810000 0x0
+ *(.eeprom*)
+ 0x00810000 __eeprom_end = .
+
+.fuse
+ *(.fuse)
+ *(.lfuse)
+ *(.hfuse)
+ *(.efuse)
+
+.lock
+ *(.lock*)
+
+.signature
+ *(.signature*)
+
+.stab 0x00000000 0x4284
+ *(.stab)
+ .stab 0x00000000 0x6b4 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/crtm8.o
+ .stab 0x000006b4 0x948 main.o
+ 0xa2c (size before relaxing)
+ .stab 0x00000ffc 0x9c0 draw.o
+ 0x16ec (size before relaxing)
+ .stab 0x000019bc 0xf24 effect.o
+ 0x1d64 (size before relaxing)
+ .stab 0x000028e0 0x54 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(cos.o)
+ 0x60 (size before relaxing)
+ .stab 0x00002934 0x21c /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_rempio2.o)
+ 0x228 (size before relaxing)
+ .stab 0x00002b50 0xfc /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_sinus.o)
+ 0x108 (size before relaxing)
+ .stab 0x00002c4c 0x1d4 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_split3.o)
+ 0x1e0 (size before relaxing)
+ .stab 0x00002e20 0x78 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(sin.o)
+ 0x84 (size before relaxing)
+ .stab 0x00002e98 0x4bc /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(addsf3x.o)
+ 0x4c8 (size before relaxing)
+ .stab 0x00003354 0x78 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_inf.o)
+ 0x84 (size before relaxing)
+ .stab 0x000033cc 0xe4 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_mpack.o)
+ 0xf0 (size before relaxing)
+ .stab 0x000034b0 0x54 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_nan.o)
+ 0x60 (size before relaxing)
+ .stab 0x00003504 0xfc /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_powsodd.o)
+ 0x108 (size before relaxing)
+ .stab 0x00003600 0x84 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_pscA.o)
+ 0x90 (size before relaxing)
+ .stab 0x00003684 0x84 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_pscB.o)
+ 0x90 (size before relaxing)
+ .stab 0x00003708 0xfc /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_round.o)
+ 0x108 (size before relaxing)
+ .stab 0x00003804 0x90 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_zero.o)
+ 0x9c (size before relaxing)
+ .stab 0x00003894 0x1ec /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(fp_powser.o)
+ 0x1f8 (size before relaxing)
+ .stab 0x00003a80 0x4d4 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libm.a(mulsf3x.o)
+ 0x4e0 (size before relaxing)
+ .stab 0x00003f54 0x330 /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/libc.a(rand.o)
+ 0x33c (size before relaxing)
+
+.stabstr 0x00000000 0x1cbd
+ *(.stabstr)
+ .stabstr 0x00000000 0x1cbd /usr/lib/gcc/avr/4.3.5/../../../avr/lib/avr4/crtm8.o
+
+.stab.excl
+ *(.stab.excl)
+
+.stab.exclstr
+ *(.stab.exclstr)
+
+.stab.index
+ *(.stab.index)
+
+.stab.indexstr
+ *(.stab.indexstr)
+
+.comment
+ *(.comment)
+
+.debug
+ *(.debug)
+
+.line
+ *(.line)
+
+.debug_srcinfo
+ *(.debug_srcinfo)
+
+.debug_sfnames
+ *(.debug_sfnames)
+
+.debug_aranges
+ *(.debug_aranges)
+
+.debug_pubnames
+ *(.debug_pubnames)
+
+.debug_info
+ *(.debug_info)
+ *(.gnu.linkonce.wi.*)
+
+.debug_abbrev
+ *(.debug_abbrev)
+
+.debug_line
+ *(.debug_line)
+
+.debug_frame
+ *(.debug_frame)
+
+.debug_str
+ *(.debug_str)
+
+.debug_loc
+ *(.debug_loc)
+
+.debug_macinfo
+ *(.debug_macinfo)
+OUTPUT(ledcube.elf elf32-avr)
+LOAD linker stubs
diff --git a/avr-test/ledcube.srec b/avr-test/ledcube.srec
new file mode 100755
index 0000000..5e86a2f
--- /dev/null
+++ b/avr-test/ledcube.srec
@@ -0,0 +1,278 @@
+S00F00006C6564637562652E7372656341
+S113000012C02CC02BC070C029C028C027C026C075
+S113001025C025C023C022C021C020C01FC01EC0CF
+S11300201DC01CC01BC011241FBECFE5D4E0DEBF21
+S1130030CDBF10E0A4E6B0E001C01D92AC3EB10714
+S1130040E1F710E0A0E6B0E0EEE2F1E102C00590D5
+S11300500D92A436B107D9F7D9D067C8D1CF1F9272
+S11300600F920FB60F921124EF92FF920F931F93EA
+S11300702F933F934F935F938F939F93E090E5006B
+S1130080F090E6000091E7001091E800A8019701C4
+S11300902E5F3F4F4F4F5F4F9091EB00892F8A5F48
+S11300A08093EB008D3748F097579093EB00A801AD
+S11300B097012D5F3F4F4F4F5F4F2093E5003093E3
+S11300C0E6004093E7005093E8009F918F915F9181
+S11300D04F913F912F911F910F91FF90EF900F90AF
+S11300E00FBE0F901F9018951F920F920FB60F928C
+S11300F011242F933F934F935F936F938F939F9309
+S1130100AF93BF93EF93FF9385B3877D85BB6091D6
+S1130110E90057E0A62FB0E0E52FF0E033E0EE0F62
+S1130120FF1F3A95E1F7EA0FFB1FEC59FF4F40819F
+S1130130AC9888B3942F91708E7F982B98BBAC9A0F
+S1130140AC9838B3842F90E095958795282F21702B
+S11301503E7F232B28BBAC9AAC9838B395958795F2
+S1130160282F21703E7F232B28BBAC9AAC9838B340
+S113017095958795282F21703E7F232B28BBAC9A19
+S1130180AC9838B395958795282F21703E7F232B03
+S113019028BBAC9AAC9838B395958795282F2170D5
+S11301A03E7F232B28BBAC9AAC9828B395958795B2
+S11301B081702E7F822B88BBAC9AAC9888B3441F85
+S11301C04427441F8E7F482B48BBAC9A515008F0FB
+S11301D0A3CF85B3962F9862887F982B95BB962FD3
+S11301E09F5F983008F090E09093E900FF91EF91C1
+S11301F0BF91AF919F918F916F915F914F913F917B
+S11302002F910F900FBE0F901F901895EF92FF92B1
+S11302100F931F9312BE83B7836083BF89B7816036
+S113022089BF8BE083BD85B5856085BD85B5886054
+S113023085BD14BC89B7806889BF12BA18BA15BACB
+S11302408FEF81BB87BB84BB789420E0EE24E394DA
+S1130250FF24FA9414C080E090E0422F50E0FC01A7
+S113026063E0EE0FFF1F6A95E1F7E40FF51FEC5909
+S1130270FF4FF08201968830910589F72F5F28306F
+S113028050F3E092A4002091E5003091E600409103
+S1130290E7005091E8008091E5009091E600A0917C
+S11302A0E700B091E800821B930BA40BB50B885EAA
+S11302B09340A040B04078F31092A40084E190E011
+S11302C06CED70E040ED57E05DD584E690E084D2BB
+S11302D085E090E061E070E0F7D484E190E068EEBE
+S11302E073E047D482E090E06AE770E04FEF5FEF9D
+S11302F024E630E008EE13E09CD1B1D510E088E7A5
+S113030060E070E046E950E021E030E05ED388E749
+S113031061E070E046E950E021E030E056D389E73F
+S113032060E070E046E950E021E030E04ED389E738
+S113033061E070E046E950E021E030E046D38AE72E
+S113034060E070E046E950E021E030E03ED38AE727
+S113035061E070E046E950E021E030E036D31F5F11
+S11303601A3069F620E077CF75D60895089778F4A7
+S113037077FD0DC06830710554F457FD08C090E056
+S1130380483051050CF091E081E0982701C090E0DD
+S1130390892F0895FF920F931F93CF93DF93F82E25
+S11303A08B01EA01E3DF8823A9F0FE0193E0EE0F5D
+S11303B0FF1F9A95E1F7E00FF11FEC59FF4F2081E1
+S11303C081E090E002C0880F991FFA94E2F78095CB
+S11303D082238083DF91CF911F910F91FF90089525
+S11303E0FF920F931F93CF93DF93F82E8B01EA01B3
+S11303F0BDDF8823A1F0FE0133E0EE0FFF1F3A9525
+S1130400E1F7E00FF11FEC59FF4F208181E090E00C
+S113041002C0880F991FFA94E2F7282B2083DF91FA
+S1130420CF911F910F91FF900895FF920F931F9307
+S1130430CF93DF93F82E8B01EA0198DF882389F0AC
+S113044043E0CC0FDD1F4A95E1F7C00FD11FCC5913
+S1130450DF4F888190E002C095958795FA94E2F782
+S11304608170DF91CF911F910F91FF9008952130FA
+S1130470310511F4B5DF08958DDF089540E050E0B3
+S113048010C0FB01E20FF31FEC59FF4F80832F5F75
+S11304903F4F28303105A9F74F5F5F4F4830510572
+S11304A049F020E030E0BA01E3E0660F771FEA95F7
+S11304B0E1F7E7CF08950BC020E000000000000042
+S11304C00000000000002F5F2A35B9F7019700975C
+S11304D099F708952F923F924F925F926F927F9275
+S11304E09F92AF92BF92CF92DF92EF92FF920F93BF
+S11304F01F93CF93DF93982E5B01CC24DD2447E038
+S1130500242E312C8FEFA8168FEFB80611F4760144
+S113051003C07101EC18FD0800E010E02701089405
+S11305204108510837010894611C711C36C08FEFD3
+S1130530A8168FEFB80611F4C30101C0C201AC01C3
+S11305408AE7981641F4C801BE016FDF282FC8015D
+S1130550BE01A70117C089E7981649F4C801BA017A
+S1130560AE0163DF282FC801B701AE010BC088E7D5
+S1130570981651F4CA01BE01A80157DF282FC701FC
+S1130580BE01A80130E073DF2196C830D10579F6A9
+S11305900F5F1F4F0830110519F0C0E0D0E0C7CF3E
+S11305A00894C11CD11C88E0C816D10409F0AACF54
+S11305B08FEFA8168FEFB80619F0EE24FF2403C0BE
+S11305C037E0E32EF12C00E010E01EC08AE7981615
+S11305D021F4C801BE01A7010DC089E7981621F4D2
+S11305E0C801B701AE0106C088E7981621F4C70117
+S11305F0BE01A801CFDE2196C830D10539F70F5FBF
+S11306001F4F0830110519F0C0E0D0E0DFCFDF91B3
+S1130610CF911F910F91FF90EF90DF90CF90BF90FB
+S1130620AF909F907F906F905F904F903F902F90EE
+S113063008952F923F924F925F926F927F928F9282
+S11306409F92AF92BF92CF92DF92EF92FF920F935D
+S11306501F93DF93CF93CDB7DEB72E970FB6F894E1
+S1130660DEBF0FBECDBF9A8389837C836B835E8399
+S11306704D8338872F831A8709874F5F5F4F21F493
+S113068097E0292E312C02C02224332489E0682EDD
+S1130690712C89819A81681A790A66DEB30132D491
+S11306A06C0162DEB3012ED47C014424552475C050
+S11306B05BDE8C0159DE9C01C80163E070E022D44A
+S11306C001978C0D9D1D9E878D87181619061CF4A5
+S11306D08615970514F0DE86CD86C90163E070E0C7
+S11306E011D48C01015010400E0D1F1D101611065F
+S11306F01CF4061517050CF087018B816D817E8132
+S1130700E9DE8D849E84AA24BB2430C0EB81FC8165
+S1130710EA37F10521F4C401B601A10115C08B81AA
+S11307209C818937910521F4C401B101A6010CC053
+S1130730EB81FC81E837F10541F44D855E854E0D72
+S11307405F1DC1016B857C854BDE0894E11CF11CA7
+S11307500894C11CD11C89819A81E816F906B4F267
+S11307600894A11CB11C0894811C911CE981FA8194
+S1130770AE16BF064CF46801EE24FF24C501800FB9
+S1130780911F9C878B87E7CF89859A8594DE08948F
+S1130790411C511CCD84DE847801EF81F8854E160E
+S11307A05F060CF485CF2E960FB6F894DEBF0FBE0D
+S11307B0CDBFCF91DF911F910F91FF90EF90DF900C
+S11307C0CF90BF90AF909F908F907F906F905F90ED
+S11307D04F903F902F900895AF92BF92CF92DF92A7
+S11307E0EF92FF920F931F93CF93DF935C01CC247E
+S11307F0DD242AC0B9DD64E070E084D3EC01EE248A
+S1130800FF2415C0B1DD8C01AFDD9C01C80168E097
+S113081070E078D3FC01C90168E070E073D3BC01D7
+S1130820CF0147E050E0DCDD0894E11CF11CEC163C
+S1130830FD0644F388EE93E03EDE8AE76FEF7FEF38
+S113084049DE0894C11CD11CCA14DB049CF2DF915C
+S1130850CF911F910F91FF90EF90DF90CF90BF90B9
+S1130860AF9008957F928F929F92AF92BF92CF9252
+S1130870DF92EF92FF920F931F93CF93DF93E82EB3
+S1130880F62E742E6901C0E0D0E0F7E08F2E912C93
+S1130890E8E0AE2EB12C87E0781661F484010C1BDD
+S11308A01D0BA5014C1B5D0B8E2D90E06F2D70E090
+S11308B071DD09C0AE01415050408E2D90E06F2D86
+S11308C070E068DD8E018E2D90E06F2D70E0A80140
+S11308D087DDC601F0DD2196C830D105E1F6DF9150
+S11308E0CF911F910F91FF90EF90DF90CF90BF9029
+S11308F0AF909F908F907F9008954F925F926F92E8
+S11309007F929F92AF92BF92CF92DF92EF92FF922B
+S11309100F931F93CF93DF93982E162F072F3A012F
+S113092080E0ACDD212F302FC9016C01C0E0D0E0A4
+S113093057E0452E512C34C06114710431F0F50197
+S11309408081A201481B510904C0F7018081482F0E
+S113095050E0FAE79F1619F4CE01B8010DC089E7FB
+S1130960981621F4CE01BA01A80106C098E7991699
+S113097021F4CA01B801AE0133DD0F5F1F4F0894A3
+S1130980A11CB11C0894E11CF11C08301105A1F64E
+S11309902196E8E0F0E0CE0EDF1EC830D10529F044
+S11309A05601760100E010E0C7CFDF91CF911F918F
+S11309B00F91FF90EF90DF90CF90BF90AF909F90FA
+S11309C07F906F905F904F9008952F923F924F9237
+S11309D05F926F927F928F929F92AF92BF92CF92CB
+S11309E0DF92EF92FF920F931F93DF93CF93CDB7D4
+S11309F0DEB7C158D0400FB6F894DEBF0FBECDBFEE
+S1130A00CF57DF4F8883C158D0402B013A014901A9
+S1130A1071E4A72EB12CAC0EBD1EF50161E8C62E03
+S1130A20D12CCC0EDD1E1192EC15FD05E1F700E092
+S1130A3010E01E010894211C311C81E088169104E9
+S1130A40B9F412C091DC60E470E05CD2E1E4F0E05F
+S1130A50EC0FFD1FE80FF91F8081882399F70F5FC2
+S1130A601F4F91E0908316C0003411055CF312C04F
+S1130A7082E08816910471F4003411055CF4E1E419
+S1130A80F0E0EC0FFD1FE00FF11F80818F5F80838A
+S1130A900F5F1F4FF501EE24FF249081892F8150B1
+S1130AA0863010F49F5F90838081873019F4089416
+S1130AB0E11CF11C3196EC15FD0579F7D101F50126
+S1130AC080814114510419F097E0981B892F8C936D
+S1130AD031961196EC15FD0599F7C301ECDCCF575F
+S1130AE0DF4F8881C158D040B10140E050E005DFBC
+S1130AF082B394E0892782BB80E4E816F10409F00C
+S1130B009CCFCF57DF4F0FB6F894DEBF0FBECDBFDB
+S1130B10CF91DF911F910F91FF90EF90DF90CF90D5
+S1130B20BF90AF909F908F907F906F905F904F9009
+S1130B303F902F900895AC01DC01FB0120E030E0F0
+S1130B409C918081981710F49F5F9C939C91808165
+S1130B50891710F491509C932F5F3F4F1196319653
+S1130B602034310569F78AE7BA0140E050E0C5DE78
+S1130B7008952F923F924F925F926F927F928F923D
+S1130B809F92AF92BF92CF92DF92EF92FF920F9318
+S1130B901F93DF93CF93CDB7DEB7C058D0400FB6C5
+S1130BA0F894DEBF0FBECDBF2C017B0100E010E046
+S1130BB05E010894A11CB11C24E0922E91E4C92E7C
+S1130BC0D12CCC0EDD1EF501E00FF11F9082CCDBA1
+S1130BD0F601E00FF11F68E070E094D180830F5FAD
+S1130BE01F4F0034110579F700E010E081E4A82ECE
+S1130BF0B12CAC0EBD1E6E010894C11CD11C370172
+S1130C00C601B5014AE797DFC30155DC0F5F1F4FEB
+S1130C1008301105A9F75701AA0CBB1CAA0CBB1C70
+S1130C20CC24DD24A1E48A2E912C8C0E9D1E1E0161
+S1130C300894211C311C2BC000E010E0C101B40158
+S1130C404AE779DFC30137DC0F5F1F4F0830110516
+S1130C50A9F7C50130DCEE24FF2486DB8C0184DB9C
+S1130C609C01C80160E470E04DD1F401E80FF91F64
+S1130C70C90168E070E046D180830894E11CF11C4E
+S1130C8080E2E816F10449F70894C11CD11CC4148D
+S1130C90D50494F2C058DF4F0FB6F894DEBF0FBEF0
+S1130CA0CDBFCF91DF911F910F91FF90EF90DF9017
+S1130CB0CF90BF90AF909F908F907F906F905F90F8
+S1130CC04F903F902F9008958F929F92AF92BF9232
+S1130CD0CF92DF92EF92FF920F931F93CF93DF9304
+S1130CE04C018B016130710511F480E001C08FEF7C
+S1130CF0C5DBC0E0D0E038DB68E070E003D1B82E9B
+S1130D00A92E32DB68E070E0FDD0D82EC92E2CDB92
+S1130D1068E070E0F7D0F82EE92E0115110551F4C2
+S1130D208B2D9A2D6D2D7C2D4F2D5E2D7EDB8130EC
+S1130D3011F70CC001301105F1F68B2D9A2D6D2D94
+S1130D407C2D4F2D5E2D71DB8823A9F68B2D9A2DDA
+S1130D506D2D7C2D4F2D5E2D980189DBC401ABDBFD
+S1130D60219681E0CF3FD80731F6DF91CF911F91D3
+S1130D700F91FF90EF90DF90CF90BF90AF909F9036
+S1130D808F9008956F927F928F929F92AF92BF92AD
+S1130D90DF92EF92FF920F931F93CF93DF933C0167
+S1130DA05B014A0180E06ADB00E010E01CC0DCDA91
+S1130DB062E070E0A7D0AC0133E0440F551F3A95D0
+S1130DC0E1F7481B590BC801BE010ADB2196C83064
+S1130DD0D10569F70F5F1F4F0830110521F4DD2499
+S1130DE0EE24FF2429C0C0E0D0E0E1CFBDDAEC015D
+S1130DF0BBDA68E070E086D0082F8E15E1F0CE01F2
+S1130E0068E070E07FD0182F8D15A9F090E0602F76
+S1130E1070E040E050E009DB882321F0812F602F4F
+S1130E2040E003C0812F602F47E095011BDDC40122
+S1130E3042DBD12EE02EF3948F2D90E0861597059A
+S1130E40ACF2DF91CF911F910F91FF90EF90DF9063
+S1130E50BF90AF909F908F907F906F900895EF9286
+S1130E60FF920F931F93CF93DF9380E007DB00E0A3
+S1130E7010E04FEEE42E42E0F42E3AC080E0FEDAB9
+S1130E80CE0119DB8FEFFADA84E690E014DBCE01B1
+S1130E9066EF7FEF37D088EE93E034D06F50704028
+S1130EA0C60FD71F1C161D064CF388EE93E003DB18
+S1130EB0CEEED2E080E0E2DAC7018C1B9D0BFBDAB8
+S1130EC08FEFDCDA84E690E0F6DACE0166EF7FEFAE
+S1130ED019D088EE93E016D06F507040C60FD71F1C
+S1130EE01C161D063CF30F5F1F4F0230110519F04D
+S1130EF0CEEED2E0C3CFDF91CF911F910F91FF903F
+S1130F00EF90089597FB092E07260AD077FD04D0A9
+S1130F100CD006D000201AF4709561957F4F089587
+S1130F20F6F7909581959F4F0895AA1BBB1B51E13D
+S1130F3007C0AA1FBB1FA617B70710F0A61BB70B45
+S1130F40881F991F5A95A9F780959095BC01CD01EA
+S1130F5008952F923F924F925F926F927F928F9259
+S1130F609F92AF92BF92CF92DF92EF92FF920F9334
+S1130F701F93CF93DF93CDB7DEB7CA1BDB0B0FB63E
+S1130F80F894DEBF0FBECDBF09942A8839884888FB
+S1130F905F846E847D848C849B84AA84B984C88491
+S1130FA0DF80EE80FD800C811B81AA81B981CE0F88
+S1130FB0D11D0FB6F894DEBF0FBECDBFED0108956D
+S1130FC0A0E0B0E0E5EEF7E0CCCFEC01A880B9807A
+S1130FD0CA80DB80A114B104C104D10441F484E2C9
+S1130FE0A82E89EDB82E8BE5C82E87E0D82EC60131
+S1130FF0B5012DE133EF41E050E05AD027EA31E466
+S113100040E050E036D07B018C01C601B5012DE1F2
+S113101033EF41E050E04CD0CA01B9012CEE34EF7B
+S11310204FEF5FEF26D06E0D7F1D801F911F97FF3E
+S113103004C06150704080409048688379838A83FB
+S11310409B839B013F77C901CDB7DEB7EAE0A5CF0B
+S1131050B7DF089580E690E0B3DF0895A0E0B0E044
+S11310608093600090936100A0936200B09363004A
+S11310700895629FD001739FF001829FE00DF11DDE
+S1131080649FE00DF11D929FF00D839FF00D749FFE
+S1131090F00D659FF00D9927729FB00DE11DF91FAA
+S11310A0639FB00DE11DF91FBD01CF011124089507
+S11310B097FB092E05260ED057FD04D014D00AD074
+S11310C0001C38F450954095309521953F4F4F4F73
+S11310D05F4F0895F6F790958095709561957F4FD1
+S11310E08F4F9F4F0895A1E21A2EAA1BBB1BFD012F
+S11310F00DC0AA1FBB1FEE1FFF1FA217B307E407F3
+S1131100F50720F0A21BB30BE40BF50B661F771F4A
+S1131110881F991F1A9469F760957095809590952A
+S11111209B01AC01BD01CF010895F894FFCFEF
+S107112E01000000B8
+S9030000FC
diff --git a/avr-test/ledcube_eeprom.bin b/avr-test/ledcube_eeprom.bin
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/avr-test/ledcube_eeprom.bin
diff --git a/avr-test/ledcube_eeprom.hex b/avr-test/ledcube_eeprom.hex
new file mode 100644
index 0000000..1996e8f
--- /dev/null
+++ b/avr-test/ledcube_eeprom.hex
@@ -0,0 +1 @@
+:00000001FF
diff --git a/avr-test/ledcube_eeprom.srec b/avr-test/ledcube_eeprom.srec
new file mode 100755
index 0000000..e2abc36
--- /dev/null
+++ b/avr-test/ledcube_eeprom.srec
@@ -0,0 +1,2 @@
+S01600006C6564637562655F656570726F6D2E7372656353
+S9030000FC
diff --git a/avr-test/mc b/avr-test/mc
new file mode 120000
index 0000000..a573d03
--- /dev/null
+++ b/avr-test/mc
@@ -0,0 +1 @@
+/home/calendros/downloads/shelve/datasheet/2011/mc \ No newline at end of file
diff --git a/avr-test/src/cube.h b/avr-test/src/cube.h
new file mode 100644
index 0000000..01f19da
--- /dev/null
+++ b/avr-test/src/cube.h
@@ -0,0 +1,32 @@
+#ifndef CUBE_H
+#define CUBE_H
+
+// Some of the functions are created to be portable
+// These functions will work on cubes of different sizes by
+// changing this constant
+#define CUBE_SIZE 8
+#define CUBE_BYTES 64
+
+// If you change this to anything greather than 8, you also have
+// change how the cube buffer works and probably all the functions
+// in draw.c
+
+// Cube buffer
+// Data from this array is loaded onto the cube for each duty cycle
+extern volatile unsigned char cube[CUBE_SIZE][CUBE_SIZE];
+
+// Framebuffer
+// Animations that take a lot of time to compute are temporarily
+// stored to this array, then loaded into cube[8][8] when the image
+// is ready to be displayed
+extern volatile unsigned char fb[CUBE_SIZE][CUBE_SIZE];
+
+// Some effects can render on different axis
+// for example send pixels along an axis
+// for better readability, we use the following predefined constants
+#define AXIS_X 0x78
+#define AXIS_Y 0x79
+#define AXIS_Z 0x7a
+
+#endif
+
diff --git a/avr-test/src/draw.cpp b/avr-test/src/draw.cpp
new file mode 100644
index 0000000..faaa346
--- /dev/null
+++ b/avr-test/src/draw.cpp
@@ -0,0 +1,559 @@
+#include "draw.h"
+#include "string.h"
+
+// Set a single voxel to ON
+void setvoxel(int x, int y, int z)
+{
+ if (inrange(x,y,z))
+ cube[z][y] |= (1 << x);
+}
+
+// Set a single voxel in the temporary cube buffer to ON
+void tmpsetvoxel(int x, int y, int z)
+{
+ if (inrange(x,y,z))
+ fb[z][y] |= (1 << x);
+}
+
+// Set a single voxel to OFF
+void clrvoxel(int x, int y, int z)
+{
+ if (inrange(x,y,z))
+ cube[z][y] &= ~(1 << x);
+}
+
+// Set a single voxel to OFF
+void tmpclrvoxel(int x, int y, int z)
+{
+ if (inrange(x,y,z))
+ fb[z][y] &= ~(1 << x);
+}
+
+// This function validates that we are drawing inside the cube.
+unsigned char inrange(int x, int y, int z)
+{
+ if (x >= 0 && x < CUBE_SIZE && y >= 0 && y < CUBE_SIZE && z >= 0 && z < CUBE_SIZE)
+ {
+ return 1;
+ } else
+ {
+ // One of the coordinates was outside the cube.
+ return 0;
+ }
+}
+
+// Get the current status of a voxel
+unsigned char getvoxel(int x, int y, int z)
+{
+ if (inrange(x,y,z))
+ {
+ if (cube[z][y] & (1 << x))
+ {
+ return 1;
+ } else
+ {
+ return 0;
+ }
+ } else
+ {
+ return 0;
+ }
+}
+
+// In some effect we want to just take bool and write it to a voxel
+// this function calls the apropriate voxel manipulation function.
+void altervoxel(int x, int y, int z, int state)
+{
+ if (state == 1)
+ {
+ setvoxel(x,y,z);
+ } else
+ {
+ clrvoxel(x,y,z);
+ }
+}
+
+// Flip the state of a voxel.
+// If the voxel is 1, its turned into a 0, and vice versa.
+void flpvoxel(int x, int y, int z)
+{
+ if (inrange(x, y, z))
+ cube[z][y] ^= (1 << x);
+}
+
+// Makes sure x1 is alwas smaller than x2
+// This is usefull for functions that uses for loops,
+// to avoid infinite loops
+void argorder(int ix1, int ix2, int *ox1, int *ox2)
+{
+ if (ix1>ix2)
+ {
+ int tmp;
+ tmp = ix1;
+ ix1= ix2;
+ ix2 = tmp;
+ }
+ *ox1 = ix1;
+ *ox2 = ix2;
+}
+
+// Sets all voxels along a X/Y plane at a given point
+// on axis Z
+void setplane_z (int z)
+{
+ int i;
+ if (z>=0 && z<CUBE_SIZE)
+ {
+ for (i=0;i<CUBE_SIZE;i++)
+ cube[z][i] = 0xff;
+ }
+}
+
+// Clears voxels in the same manner as above
+void clrplane_z (int z)
+{
+ int i;
+ if (z>=0 && z<CUBE_SIZE)
+ {
+ for (i=0;i<CUBE_SIZE;i++)
+ cube[z][i] = 0x00;
+ }
+}
+
+void setplane_x (int x)
+{
+ int z;
+ int y;
+ if (x>=0 && x<CUBE_SIZE)
+ {
+ for (z=0;z<CUBE_SIZE;z++)
+ {
+ for (y=0;y<CUBE_SIZE;y++)
+ {
+ cube[z][y] |= (1 << x);
+ }
+ }
+ }
+}
+
+void clrplane_x (int x)
+{
+ int z;
+ int y;
+ if (x>=0 && x<CUBE_SIZE)
+ {
+ for (z=0;z<CUBE_SIZE;z++)
+ {
+ for (y=0;y<CUBE_SIZE;y++)
+ {
+ cube[z][y] &= ~(1 << x);
+ }
+ }
+ }
+}
+
+void setplane_y (int y)
+{
+ int z;
+ if (y>=0 && y<CUBE_SIZE)
+ {
+ for (z=0;z<CUBE_SIZE;z++)
+ cube[z][y] = 0xff;
+ }
+}
+
+void clrplane_y (int y)
+{
+ int z;
+ if (y>=0 && y<CUBE_SIZE)
+ {
+ for (z=0;z<CUBE_SIZE;z++)
+ cube[z][y] = 0x00;
+ }
+}
+
+void setplane (char axis, unsigned char i)
+{
+ switch (axis)
+ {
+ case AXIS_X:
+ setplane_x(i);
+ break;
+
+ case AXIS_Y:
+ setplane_y(i);
+ break;
+
+ case AXIS_Z:
+ setplane_z(i);
+ break;
+ }
+}
+
+void clrplane (char axis, unsigned char i)
+{
+ switch (axis)
+ {
+ case AXIS_X:
+ clrplane_x(i);
+ break;
+
+ case AXIS_Y:
+ clrplane_y(i);
+ break;
+
+ case AXIS_Z:
+ clrplane_z(i);
+ break;
+ }
+}
+
+// Fill a value into all 64 byts of the cube buffer
+// Mostly used for clearing. fill(0x00)
+// or setting all on. fill(0xff)
+void fill (unsigned char pattern)
+{
+ int z;
+ int y;
+ for (z=0;z<CUBE_SIZE;z++)
+ {
+ for (y=0;y<CUBE_SIZE;y++)
+ {
+ cube[z][y] = pattern;
+ }
+ }
+}
+
+void tmpfill (unsigned char pattern)
+{
+ int z;
+ int y;
+ for (z=0;z<CUBE_SIZE;z++)
+ {
+ for (y=0;y<CUBE_SIZE;y++)
+ {
+ fb[z][y] = pattern;
+ }
+ }
+}
+
+// Draw a box with all walls drawn and all voxels inside set
+void box_filled(int x1, int y1, int z1, int x2, int y2, int z2)
+{
+ int iy;
+ int iz;
+
+ argorder(x1, x2, &x1, &x2);
+ argorder(y1, y2, &y1, &y2);
+ argorder(z1, z2, &z1, &z2);
+
+ for (iz=z1;iz<=z2;iz++)
+ {
+ for (iy=y1;iy<=y2;iy++)
+ {
+ cube[iz][iy] |= byteline(x1,x2);
+ }
+ }
+
+}
+
+// Darw a hollow box with side walls.
+void box_walls(int x1, int y1, int z1, int x2, int y2, int z2)
+{
+ int iy;
+ int iz;
+
+ argorder(x1, x2, &x1, &x2);
+ argorder(y1, y2, &y1, &y2);
+ argorder(z1, z2, &z1, &z2);
+
+ for (iz=z1;iz<=z2;iz++)
+ {
+ for (iy=y1;iy<=y2;iy++)
+ {
+ if (iy == y1 || iy == y2 || iz == z1 || iz == z2)
+ {
+ cube[iz][iy] = byteline(x1,x2);
+ } else
+ {
+ cube[iz][iy] |= ((0x01 << x1) | (0x01 << x2));
+ }
+ }
+ }
+
+}
+
+// Draw a wireframe box. This only draws the corners and edges,
+// no walls.
+void box_wireframe(int x1, int y1, int z1, int x2, int y2, int z2)
+{
+ int iy;
+ int iz;
+
+ argorder(x1, x2, &x1, &x2);
+ argorder(y1, y2, &y1, &y2);
+ argorder(z1, z2, &z1, &z2);
+
+ // Lines along X axis
+ cube[z1][y1] = byteline(x1,x2);
+ cube[z1][y2] = byteline(x1,x2);
+ cube[z2][y1] = byteline(x1,x2);
+ cube[z2][y2] = byteline(x1,x2);
+
+ // Lines along Y axis
+ for (iy=y1;iy<=y2;iy++)
+ {
+ setvoxel(x1,iy,z1);
+ setvoxel(x1,iy,z2);
+ setvoxel(x2,iy,z1);
+ setvoxel(x2,iy,z2);
+ }
+
+ // Lines along Z axis
+ for (iz=z1;iz<=z2;iz++)
+ {
+ setvoxel(x1,y1,iz);
+ setvoxel(x1,y2,iz);
+ setvoxel(x2,y1,iz);
+ setvoxel(x2,y2,iz);
+ }
+
+}
+
+// Returns a byte with a row of 1's drawn in it.
+// byteline(2,5) gives 0b00111100
+char byteline (int start, int end)
+{
+ return ((0xff<<start) & ~(0xff<<(end+1)));
+}
+
+// Flips a byte 180 degrees.
+// MSB becomes LSB, LSB becomes MSB.
+char flipbyte (char byte)
+{
+ char flop = 0x00;
+
+ flop = (flop & 0b11111110) | (0b00000001 & (byte >> 7));
+ flop = (flop & 0b11111101) | (0b00000010 & (byte >> 5));
+ flop = (flop & 0b11111011) | (0b00000100 & (byte >> 3));
+ flop = (flop & 0b11110111) | (0b00001000 & (byte >> 1));
+ flop = (flop & 0b11101111) | (0b00010000 & (byte << 1));
+ flop = (flop & 0b11011111) | (0b00100000 & (byte << 3));
+ flop = (flop & 0b10111111) | (0b01000000 & (byte << 5));
+ flop = (flop & 0b01111111) | (0b10000000 & (byte << 7));
+ return flop;
+}
+
+// Draw a line between any coordinates in 3d space.
+// Uses integer values for input, so dont expect smooth animations.
+void line(int x1, int y1, int z1, int x2, int y2, int z2)
+{
+ float xy; // how many voxels do we move on the y axis for each step on the x axis
+ float xz; // how many voxels do we move on the y axis for each step on the x axis
+ unsigned char x,y,z;
+ unsigned char lasty,lastz;
+
+ // We always want to draw the line from x=0 to x=7.
+ // If x1 is bigget than x2, we need to flip all the values.
+ if (x1>x2)
+ {
+ int tmp;
+ tmp = x2; x2 = x1; x1 = tmp;
+ tmp = y2; y2 = y1; y1 = tmp;
+ tmp = z2; z2 = z1; z1 = tmp;
+ }
+
+
+ if (y1>y2)
+ {
+ xy = (float)(y1-y2)/(float)(x2-x1);
+ lasty = y2;
+ } else
+ {
+ xy = (float)(y2-y1)/(float)(x2-x1);
+ lasty = y1;
+ }
+
+ if (z1>z2)
+ {
+ xz = (float)(z1-z2)/(float)(x2-x1);
+ lastz = z2;
+ } else
+ {
+ xz = (float)(z2-z1)/(float)(x2-x1);
+ lastz = z1;
+ }
+
+
+
+ // For each step of x, y increments by:
+ for (x = x1; x<=x2;x++)
+ {
+ y = (xy*(x-x1))+y1;
+ z = (xz*(x-x1))+z1;
+ setvoxel(x,y,z);
+ }
+
+}
+
+// Delay loop.
+// This is not calibrated to milliseconds,
+// but we had allready made to many effects using this
+// calibration when we figured it might be a good idea
+// to calibrate it.
+void delay_ms(uint16_t x)
+{
+ uint8_t y, z;
+ for ( ; x > 0 ; x--){
+ for ( y = 0 ; y < 90 ; y++){
+ for ( z = 0 ; z < 6 ; z++){
+ asm volatile ("nop");
+ }
+ }
+ }
+}
+
+// Copies the contents of fb (temp cube buffer) into the rendering buffer
+void tmp2cube (void)
+{
+ memcpy((void*)cube, (const void*)fb, 64); // copy the current cube into a buffer.
+}
+
+// Shift the entire contents of the cube along an axis
+// This is great for effects where you want to draw something
+// on one side of the cube and have it flow towards the other
+// side. Like rain flowing down the Z axiz.
+void shift (char axis, int direction)
+{
+ int i, x ,y;
+ int ii, iii;
+ int state;
+
+ for (i = 0; i < CUBE_SIZE; i++)
+ {
+ if (direction == -1)
+ {
+ ii = i;
+ } else
+ {
+ ii = (7-i);
+ }
+
+
+ for (x = 0; x < CUBE_SIZE; x++)
+ {
+ for (y = 0; y < CUBE_SIZE; y++)
+ {
+ if (direction == -1)
+ {
+ iii = ii+1;
+ } else
+ {
+ iii = ii-1;
+ }
+
+ if (axis == AXIS_Z)
+ {
+ state = getvoxel(x,y,iii);
+ altervoxel(x,y,ii,state);
+ }
+
+ if (axis == AXIS_Y)
+ {
+ state = getvoxel(x,iii,y);
+ altervoxel(x,ii,y,state);
+ }
+
+ if (axis == AXIS_X)
+ {
+ state = getvoxel(iii,y,x);
+ altervoxel(ii,y,x,state);
+ }
+ }
+ }
+ }
+
+ if (direction == -1)
+ {
+ i = 7;
+ } else
+ {
+ i = 0;
+ }
+
+ for (x = 0; x < CUBE_SIZE; x++)
+ {
+ for (y = 0; y < CUBE_SIZE; y++)
+ {
+ if (axis == AXIS_Z)
+ clrvoxel(x,y,i);
+
+ if (axis == AXIS_Y)
+ clrvoxel(x,i,y);
+
+ if (axis == AXIS_X)
+ clrvoxel(i,y,x);
+ }
+ }
+}
+
+// Flip the cube 180 degrees along the y axis.
+void mirror_y (void)
+{
+ unsigned char buffer[CUBE_SIZE][CUBE_SIZE];
+ unsigned char x,y,z;
+
+ memcpy(buffer, (const void*)cube, CUBE_BYTES); // copy the current cube into a buffer.
+
+ fill(0x00);
+ for (z=0; z<CUBE_SIZE; z++)
+ {
+ for (y=0; y<CUBE_SIZE; y++)
+ {
+ for (x=0; x<CUBE_SIZE; x++)
+ {
+ if (buffer[z][y] & (0x01 << x))
+ setvoxel(x,CUBE_SIZE-1-y,z);
+ }
+ }
+ }
+
+}
+
+// Flip the cube 180 degrees along the x axis
+void mirror_x (void)
+{
+ unsigned char buffer[CUBE_SIZE][CUBE_SIZE];
+ unsigned char y,z;
+
+ memcpy(buffer, (const void*)cube, CUBE_BYTES); // copy the current cube into a buffer.
+
+ fill(0x00);
+
+ for (z=0; z<CUBE_SIZE; z++)
+ {
+ for (y=0; y<CUBE_SIZE; y++)
+ {
+ // This will break with different buffer sizes..
+ cube[z][y] = flipbyte(buffer[z][y]);
+ }
+ }
+}
+
+// flip the cube 180 degrees along the z axis
+void mirror_z (void)
+{
+ unsigned char buffer[CUBE_SIZE][CUBE_SIZE];
+ unsigned char z, y;
+
+ memcpy(buffer, (const void*)cube, CUBE_BYTES); // copy the current cube into a buffer.
+
+ for (y=0; y<CUBE_SIZE; y++)
+ {
+ for (z=0; z<CUBE_SIZE; z++)
+ {
+ cube[CUBE_SIZE-1-z][y] = buffer[z][y];
+ }
+ }
+}
+
diff --git a/avr-test/src/draw.h b/avr-test/src/draw.h
new file mode 100644
index 0000000..abe93d2
--- /dev/null
+++ b/avr-test/src/draw.h
@@ -0,0 +1,71 @@
+#ifndef DRAW_H
+#define DRAW_H
+
+#include <avr/io.h>
+#include <avr/pgmspace.h>
+
+#include "cube.h"
+
+extern const unsigned char font[480];
+
+// Red led on D2
+#define LED_RED 0x04
+// Green led D3
+#define LED_GREEN 0x08
+// Program led on D4
+#define LED_PGM 0x10;
+// Leds connected to port D
+#define LED_PORT PORTD
+// Programming button on D5
+#define PGM_BTN 0x20
+
+void delay_ms (uint16_t x);
+
+
+void setvoxel(int x, int y, int z);
+void clrvoxel(int x, int y, int z);
+void tmpsetvoxel(int x, int y, int z);
+void tmpclrvoxel(int x, int y, int z);
+
+unsigned char inrange(int x, int y, int z);
+unsigned char getvoxel(int x, int y, int z);
+void flpvoxel(int x, int y, int z);
+
+void altervoxel(int x, int y, int z, int state);
+void setplane_z(int z);
+void clrplane_z(int z);
+void setplane_x(int x);
+void clrplane_x(int x);
+void setplane_y(int y);
+void clrplane_y(int y);
+
+void setplane (char axis, unsigned char i);
+void clrplane (char axis, unsigned char i);
+
+void setline_z(int x, int y, int z1, int z2);
+void setline_x(int z, int y, int x1, int x2);
+void setline_y(int z, int x, int y1, int y2);
+void clrline_z(int x, int y, int z1, int z2);
+void clrline_x(int z, int y, int x1, int x2);
+void clrline_y(int z, int x, int y1, int y2);
+void fill(unsigned char pattern);
+void tmpfill(unsigned char pattern);
+void line(int x1, int y1, int z1, int x2, int y2, int z2);
+void drawchar(char chr, int offset, int layer);
+char flipbyte(char byte);
+void charfly (char chr, int direction, char axis, int mode, uint16_t delay);
+void strfly (char * str, int direction, char axis, int mode, uint16_t delay, uint16_t pause);
+void box_filled(int x1, int y1, int z1, int x2, int y2, int z2);
+void box_walls(int x1, int y1, int z1, int x2, int y2, int z2);
+void box_wireframe(int x1, int y1, int z1, int x2, int y2, int z2);
+char byteline (int start, int end);
+
+void tmp2cube (void);
+void shift (char axis, int direction);
+
+void mirror_x(void);
+void mirror_y(void);
+void mirror_z(void);
+
+#endif
+
diff --git a/avr-test/src/effect.cpp b/avr-test/src/effect.cpp
new file mode 100644
index 0000000..1f47155
--- /dev/null
+++ b/avr-test/src/effect.cpp
@@ -0,0 +1,1021 @@
+#include "effect.h"
+#include "draw.h"
+#include <math.h>
+#include <avr/interrupt.h>
+
+//char myrand();
+int myrand();
+
+void effect_test (void)
+{
+
+ int x,y,i;
+
+ for (i=0;i<1000;i++)
+ {
+ x = sin(i/8)*2+3.5;
+ y = cos(i/8)*2+3.5;
+
+ setvoxel(x,y,1);
+ setvoxel(x,y,1);
+ delay_ms(1000);
+ fill(0x00);
+ }
+
+}
+
+
+// Draw a plane on one axis and send it back and forth once.
+void effect_planboing (int plane, int speed)
+{
+ int i;
+ for (i=0;i<8;i++)
+ {
+ fill(0x00);
+ setplane(plane, i);
+ delay_ms(speed);
+ }
+
+ for (i=7;i>=0;i--)
+ {
+ fill(0x00);
+ setplane(plane,i);
+ delay_ms(speed);
+ }
+}
+
+void effect_blinky2()
+{
+ int i,r;
+ fill(0x00);
+
+ for (r=0;r<2;r++)
+ {
+ i = 750;
+ while (i>0)
+ {
+ fill(0x00);
+ delay_ms(i);
+
+ fill(0xff);
+ delay_ms(100);
+
+ i = i - (15+(1000/(i/10)));
+ }
+
+ delay_ms(1000);
+
+ i = 750;
+ while (i>0)
+ {
+ fill(0x00);
+ delay_ms(751-i);
+
+ fill(0xff);
+ delay_ms(100);
+
+ i = i - (15+(1000/(i/10)));
+ }
+ }
+
+}
+
+void effect_box_shrink_grow (int iterations, int rot, int flip, uint16_t delay)
+{
+ int x, i, xyz;
+ for (x=0;x<iterations;x++)
+ {
+ for (i=0;i<16;i++)
+ {
+ xyz = 7-i; // This reverses counter i between 0 and 7.
+ if (i > 7)
+ xyz = i-8; // at i > 7, i 8-15 becomes xyz 0-7.
+
+ fill(0x00); delay_ms(1);
+ cli(); // disable interrupts while the cube is being rotated
+ box_wireframe(0,0,0,xyz,xyz,xyz);
+
+ if (flip > 0) // upside-down
+ mirror_z();
+
+ if (rot == 1 || rot == 3)
+ mirror_y();
+
+ if (rot == 2 || rot == 3)
+ mirror_x();
+
+ sei(); // enable interrupts
+ delay_ms(delay);
+ fill(0x00);
+ }
+ }
+}
+
+// Creates a wireframe box that shrinks or grows out from the center of the cube.
+void effect_box_woopwoop (int delay, int grow)
+{
+ int i,ii;
+
+ fill(0x00);
+ for (i=0;i<4;i++)
+ {
+ ii = i;
+ if (grow > 0)
+ ii = 3-i;
+
+ box_wireframe(4+ii,4+ii,4+ii,3-ii,3-ii,3-ii);
+ delay_ms(delay);
+ fill(0x00);
+ }
+}
+
+
+// Send a voxel flying from one side of the cube to the other
+// If its at the bottom, send it to the top..
+void sendvoxel_z (unsigned char x, unsigned char y, unsigned char z, int delay)
+{
+ int i, ii;
+ for (i=0; i<8; i++)
+ {
+ if (z == 7)
+ {
+ ii = 7-i;
+ clrvoxel(x,y,ii+1);
+ } else
+ {
+ ii = i;
+ clrvoxel(x,y,ii-1);
+ }
+ setvoxel(x,y,ii);
+ delay_ms(delay);
+ }
+}
+
+// Send all the voxels from one side of the cube to the other
+// Start at z and send to the opposite side.
+// Sends in random order.
+void sendplane_rand_z (unsigned char z, int delay, int wait)
+{
+ unsigned char loop = 16;
+ unsigned char x, y;
+
+ fill(0x00);
+
+ setplane_z(z);
+
+ // Send voxels at random untill all 16 have crossed the cube.
+ while(loop)
+ {
+ x = myrand()%4;
+ y = myrand()%4;
+ if (getvoxel(x,y,z))
+ {
+ // Send the voxel flying
+ sendvoxel_z(x,y,z,delay);
+ delay_ms(wait);
+ loop--; // one down, loop-- to go. when this hits 0, the loop exits.
+ }
+ }
+}
+
+// For each coordinate along X and Y, a voxel is set either at level 0 or at level 7
+// for n iterations, a random voxel is sent to the opposite side of where it was.
+void sendvoxels_rand_z (int iterations, int delay, int wait)
+{
+ unsigned char x, y, last_x = 0, last_y = 0, i;
+
+ fill(0x00);
+
+ // Loop through all the X and Y coordinates
+ for (x=0;x<8;x++)
+ {
+ for (y=0;y<8;y++)
+ {
+ // Then set a voxel either at the top or at the bottom
+ // myrand()%2 returns either 0 or 1. multiplying by 7 gives either 0 or 7.
+ setvoxel(x,y,((myrand()%2)*7));
+ }
+ }
+
+ for (i=0;i<iterations;i++)
+ {
+ // Pick a random x,y position
+ x = myrand()%8;
+ y = myrand()%8;
+ // but not the sameone twice in a row
+ if (y != last_y && x != last_x)
+ {
+ // If the voxel at this x,y is at the bottom
+ if (getvoxel(x,y,0))
+ {
+ // send it to the top
+ sendvoxel_z(x,y,0,delay);
+ } else
+ {
+ // if its at the top, send it to the bottom
+ sendvoxel_z(x,y,7,delay);
+ }
+ delay_ms(wait);
+
+ // Remember the last move
+ last_y = y;
+ last_x = x;
+ }
+ }
+
+}
+
+
+// Big ugly function :p but it looks pretty
+void boingboing(uint16_t iterations, int delay, unsigned char mode, unsigned char drawmode)
+{
+ fill(0x00); // Blank the cube
+
+ int x, y, z; // Current coordinates for the point
+ int dx, dy, dz; // Direction of movement
+ int lol, i; // lol?
+ unsigned char crash_x, crash_y, crash_z;
+
+ y = myrand()%8;
+ x = myrand()%8;
+ z = myrand()%8;
+
+ // Coordinate array for the snake.
+ int snake[8][3];
+ for (i=0;i<8;i++)
+ {
+ snake[i][0] = x;
+ snake[i][1] = y;
+ snake[i][2] = z;
+ }
+
+
+ dx = 1;
+ dy = 1;
+ dz = 1;
+
+ while(iterations)
+ {
+ crash_x = 0;
+ crash_y = 0;
+ crash_z = 0;
+
+
+ // Let's mix things up a little:
+ if (myrand()%3 == 0)
+ {
+ // Pick a random axis, and set the speed to a random number.
+ lol = myrand()%3;
+ if (lol == 0)
+ dx = myrand()%3 - 1;
+
+ if (lol == 1)
+ dy = myrand()%3 - 1;
+
+ if (lol == 2)
+ dz = myrand()%3 - 1;
+ }
+
+ // The point has reached 0 on the x-axis and is trying to go to -1
+ // aka a crash
+ if (dx == -1 && x == 0)
+ {
+ crash_x = 0x01;
+ if (myrand()%3 == 1)
+ {
+ dx = 1;
+ } else
+ {
+ dx = 0;
+ }
+ }
+
+ // y axis 0 crash
+ if (dy == -1 && y == 0)
+ {
+ crash_y = 0x01;
+ if (myrand()%3 == 1)
+ {
+ dy = 1;
+ } else
+ {
+ dy = 0;
+ }
+ }
+
+ // z axis 0 crash
+ if (dz == -1 && z == 0)
+ {
+ crash_z = 0x01;
+ if (myrand()%3 == 1)
+ {
+ dz = 1;
+ } else
+ {
+ dz = 0;
+ }
+ }
+
+ // x axis 7 crash
+ if (dx == 1 && x == 7)
+ {
+ crash_x = 0x01;
+ if (myrand()%3 == 1)
+ {
+ dx = -1;
+ } else
+ {
+ dx = 0;
+ }
+ }
+
+ // y axis 7 crash
+ if (dy == 1 && y == 7)
+ {
+ crash_y = 0x01;
+ if (myrand()%3 == 1)
+ {
+ dy = -1;
+ } else
+ {
+ dy = 0;
+ }
+ }
+
+ // z azis 7 crash
+ if (dz == 1 && z == 7)
+ {
+ crash_z = 0x01;
+ if (myrand()%3 == 1)
+ {
+ dz = -1;
+ } else
+ {
+ dz = 0;
+ }
+ }
+
+ // mode bit 0 sets crash action enable
+ if (mode | 0x01)
+ {
+ if (crash_x)
+ {
+ if (dy == 0)
+ {
+ if (y == 7)
+ {
+ dy = -1;
+ } else if (y == 0)
+ {
+ dy = +1;
+ } else
+ {
+ if (myrand()%2 == 0)
+ {
+ dy = -1;
+ } else
+ {
+ dy = 1;
+ }
+ }
+ }
+ if (dz == 0)
+ {
+ if (z == 7)
+ {
+ dz = -1;
+ } else if (z == 0)
+ {
+ dz = 1;
+ } else
+ {
+ if (myrand()%2 == 0)
+ {
+ dz = -1;
+ } else
+ {
+ dz = 1;
+ }
+ }
+ }
+ }
+
+ if (crash_y)
+ {
+ if (dx == 0)
+ {
+ if (x == 7)
+ {
+ dx = -1;
+ } else if (x == 0)
+ {
+ dx = 1;
+ } else
+ {
+ if (myrand()%2 == 0)
+ {
+ dx = -1;
+ } else
+ {
+ dx = 1;
+ }
+ }
+ }
+ if (dz == 0)
+ {
+ if (z == 3)
+ {
+ dz = -1;
+ } else if (z == 0)
+ {
+ dz = 1;
+ } else
+ {
+ if (myrand()%2 == 0)
+ {
+ dz = -1;
+ } else
+ {
+ dz = 1;
+ }
+ }
+ }
+ }
+
+ if (crash_z)
+ {
+ if (dy == 0)
+ {
+ if (y == 7)
+ {
+ dy = -1;
+ } else if (y == 0)
+ {
+ dy = 1;
+ } else
+ {
+ if (myrand()%2 == 0)
+ {
+ dy = -1;
+ } else
+ {
+ dy = 1;
+ }
+ }
+ }
+ if (dx == 0)
+ {
+ if (x == 7)
+ {
+ dx = -1;
+ } else if (x == 0)
+ {
+ dx = 1;
+ } else
+ {
+ if (myrand()%2 == 0)
+ {
+ dx = -1;
+ } else
+ {
+ dx = 1;
+ }
+ }
+ }
+ }
+ }
+
+ // mode bit 1 sets corner avoid enable
+ if (mode | 0x02)
+ {
+ if ( // We are in one of 8 corner positions
+ (x == 0 && y == 0 && z == 0) ||
+ (x == 0 && y == 0 && z == 7) ||
+ (x == 0 && y == 7 && z == 0) ||
+ (x == 0 && y == 7 && z == 7) ||
+ (x == 7 && y == 0 && z == 0) ||
+ (x == 7 && y == 0 && z == 7) ||
+ (x == 7 && y == 7 && z == 0) ||
+ (x == 7 && y == 7 && z == 7)
+ )
+ {
+ // At this point, the voxel would bounce
+ // back and forth between this corner,
+ // and the exact opposite corner
+ // We don't want that!
+
+ // So we alter the trajectory a bit,
+ // to avoid corner stickyness
+ lol = myrand()%3;
+ if (lol == 0)
+ dx = 0;
+
+ if (lol == 1)
+ dy = 0;
+
+ if (lol == 2)
+ dz = 0;
+ }
+ }
+
+ // one last sanity check
+ if (x == 0 && dx == -1)
+ dx = 1;
+
+ if (y == 0 && dy == -1)
+ dy = 1;
+
+ if (z == 0 && dz == -1)
+ dz = 1;
+
+ if (x == 7 && dx == 1)
+ dx = -1;
+
+ if (y == 7 && dy == 1)
+ dy = -1;
+
+ if (z == 7 && dz == 1)
+ dz = -1;
+
+
+ // Finally, move the voxel.
+ x = x + dx;
+ y = y + dy;
+ z = z + dz;
+
+ if (drawmode == 0x01) // show one voxel at time
+ {
+ setvoxel(x,y,z);
+ delay_ms(delay);
+ clrvoxel(x,y,z);
+ } else if (drawmode == 0x02) // flip the voxel in question
+ {
+ flpvoxel(x,y,z);
+ delay_ms(delay);
+ } if (drawmode == 0x03) // draw a snake
+ {
+ for (i=7;i>=0;i--)
+ {
+ snake[i][0] = snake[i-1][0];
+ snake[i][1] = snake[i-1][1];
+ snake[i][2] = snake[i-1][2];
+ }
+ snake[0][0] = x;
+ snake[0][1] = y;
+ snake[0][2] = z;
+
+ for (i=0;i<8;i++)
+ {
+ setvoxel(snake[i][0],snake[i][1],snake[i][2]);
+ }
+ delay_ms(delay);
+ for (i=0;i<8;i++)
+ {
+ clrvoxel(snake[i][0],snake[i][1],snake[i][2]);
+ }
+ }
+
+
+ iterations--;
+ }
+}
+
+// Set or clear exactly 512 voxels in a random order.
+void effect_random_filler (int delay, int state)
+{
+ int x,y,z;
+ int loop = 0;
+
+
+ if (state == 1)
+ {
+ fill(0x00);
+ } else
+ {
+ fill(0xff);
+ }
+
+ while (loop<511)
+ {
+ x = myrand()%8;
+ y = myrand()%8;
+ z = myrand()%8;
+
+ if ((state == 0 && getvoxel(x,y,z) == 0x01) || (state == 1 && getvoxel(x,y,z) == 0x00))
+ {
+ altervoxel(x,y,z,state);
+ delay_ms(delay);
+ loop++;
+ }
+ }
+}
+
+
+void effect_rain (int iterations)
+{
+ int i, ii;
+ int rnd_x;
+ int rnd_y;
+ int rnd_num;
+
+ for (ii=0;ii<iterations;ii++)
+ {
+ rnd_num = myrand()%4;
+
+ for (i=0; i < rnd_num;i++)
+ {
+ rnd_x = myrand()%8;
+ rnd_y = myrand()%8;
+ setvoxel(rnd_x,rnd_y,7);
+ }
+
+ delay_ms(1000);
+ shift(AXIS_Z,-1);
+ }
+}
+
+void effect_z_updown (int iterations, int delay)
+{
+ unsigned char positions[64];
+ unsigned char destinations[64];
+
+ int i,y,move;
+
+ for (i=0; i<64; i++)
+ {
+ positions[i] = 4;
+ destinations[i] = myrand()%8;
+ }
+
+ for (i=0; i<8; i++)
+ {
+ effect_z_updown_move(positions, destinations, AXIS_Z);
+ delay_ms(delay);
+ }
+
+ for (i=0;i<iterations;i++)
+ {
+ for (move=0;move<8;move++)
+ {
+ effect_z_updown_move(positions, destinations, AXIS_Z);
+ delay_ms(delay);
+ }
+
+ delay_ms(delay*4);
+
+
+ for (y=0;y<32;y++)
+ {
+ destinations[myrand()%64] = myrand()%8;
+ }
+
+ }
+
+}
+
+void effect_z_updown_move (unsigned char positions[64], unsigned char destinations[64], char axis)
+{
+ int px;
+ for (px=0; px<64; px++)
+ {
+ if (positions[px]<destinations[px])
+ {
+ positions[px]++;
+ }
+ if (positions[px]>destinations[px])
+ {
+ positions[px]--;
+ }
+ }
+
+ draw_positions_axis (AXIS_Z, positions,0);
+}
+
+void effect_axis_updown_randsuspend (char axis, int delay, int sleep, int invert)
+{
+ unsigned char positions[64];
+ unsigned char destinations[64];
+
+ int i,px;
+
+ // Set 64 random positions
+ for (i=0; i<64; i++)
+ {
+ positions[i] = 0; // Set all starting positions to 0
+ destinations[i] = myrand()%8;
+ }
+
+ // Loop 8 times to allow destination 7 to reach all the way
+ for (i=0; i<8; i++)
+ {
+ // For every iteration, move all position one step closer to their destination
+ for (px=0; px<64; px++)
+ {
+ if (positions[px]<destinations[px])
+ {
+ positions[px]++;
+ }
+ }
+ // Draw the positions and take a nap
+ draw_positions_axis (axis, positions,invert);
+ delay_ms(delay);
+ }
+
+ // Set all destinations to 7 (opposite from the side they started out)
+ for (i=0; i<64; i++)
+ {
+ destinations[i] = 7;
+ }
+
+ // Suspend the positions in mid-air for a while
+ delay_ms(sleep);
+
+ // Then do the same thing one more time
+ for (i=0; i<8; i++)
+ {
+ for (px=0; px<64; px++)
+ {
+ if (positions[px]<destinations[px])
+ {
+ positions[px]++;
+ }
+ if (positions[px]>destinations[px])
+ {
+ positions[px]--;
+ }
+ }
+ draw_positions_axis (axis, positions,invert);
+ delay_ms(delay);
+ }
+}
+
+void draw_positions_axis (char axis, unsigned char positions[64], int invert)
+{
+ int x, y, p;
+
+ fill(0x00);
+
+ for (x=0; x<8; x++)
+ {
+ for (y=0; y<8; y++)
+ {
+ if (invert)
+ {
+ p = (7-positions[(x*8)+y]);
+ } else
+ {
+ p = positions[(x*8)+y];
+ }
+
+ if (axis == AXIS_Z)
+ setvoxel(x,y,p);
+
+ if (axis == AXIS_Y)
+ setvoxel(x,p,y);
+
+ if (axis == AXIS_X)
+ setvoxel(p,y,x);
+ }
+ }
+
+}
+
+
+void effect_boxside_randsend_parallel (char axis, int origin, int delay, int mode)
+{
+ int i;
+ int done;
+ unsigned char cubepos[64];
+ unsigned char pos[64];
+ int notdone = 1;
+ int notdone2 = 1;
+ int sent = 0;
+
+ for (i=0;i<64;i++)
+ {
+ pos[i] = 0;
+ }
+
+ while (notdone)
+ {
+ if (mode == 1)
+ {
+ notdone2 = 1;
+ while (notdone2 && sent<64)
+ {
+ i = myrand()%64;
+ if (pos[i] == 0)
+ {
+ sent++;
+ pos[i] += 1;
+ notdone2 = 0;
+ }
+ }
+ } else if (mode == 2)
+ {
+ if (sent<64)
+ {
+ pos[sent] += 1;
+ sent++;
+ }
+ }
+
+ done = 0;
+ for (i=0;i<64;i++)
+ {
+ if (pos[i] > 0 && pos[i] <7)
+ {
+ pos[i] += 1;
+ }
+
+ if (pos[i] == 7)
+ done++;
+ }
+
+ if (done == 64)
+ notdone = 0;
+
+ for (i=0;i<64;i++)
+ {
+ if (origin == 0)
+ {
+ cubepos[i] = pos[i];
+ } else
+ {
+ cubepos[i] = (7-pos[i]);
+ }
+ }
+
+
+ delay_ms(delay);
+ draw_positions_axis(axis,cubepos,0);
+ LED_PORT ^= LED_RED;
+ }
+
+}
+
+
+
+
+// Light all leds layer by layer,
+// then unset layer by layer
+void effect_loadbar(int delay)
+{
+ fill(0x00);
+
+ int z,y;
+
+ for (z=0;z<8;z++)
+ {
+ for (y=0;y<8;y++)
+ cube[z][y] = 0xff;
+
+ delay_ms(delay);
+ }
+
+ delay_ms(delay*3);
+
+ for (z=0;z<8;z++)
+ {
+ for (y=0;y<8;y++)
+ cube[z][y] = 0x00;
+
+ delay_ms(delay);
+ }
+}
+
+
+// Set n number of voxels at random positions
+void effect_random_sparkle_flash (int iterations, int voxels, int delay)
+{
+ int i;
+ int v;
+ for (i = 0; i < iterations; i++)
+ {
+ for (v=0;v<=voxels;v++)
+ setvoxel(myrand()%8,myrand()%8,myrand()%8);
+
+ delay_ms(delay);
+ fill(0x00);
+ }
+}
+
+// blink 1 random voxel, blink 2 random voxels..... blink 20 random voxels
+// and back to 1 again.
+void effect_random_sparkle (void)
+{
+ int i;
+
+ for (i=1;i<20;i++)
+ {
+ effect_random_sparkle_flash(5,i,200);
+ }
+
+ for (i=20;i>=1;i--)
+ {
+ effect_random_sparkle_flash(5,i,200);
+ }
+
+}
+
+int effect_telcstairs_do(int x, int val, int delay)
+{
+ int y,z;
+
+ for(y = 0, z = x; y <= z; y++, x--)
+ {
+ if(x < CUBE_SIZE && y < CUBE_SIZE)
+ {
+ cube[x][y] = val;
+ }
+ }
+ delay_ms(delay);
+ return z;
+}
+
+void effect_telcstairs (int invert, int delay, int val)
+{
+ int x;
+
+ if(invert)
+ {
+ for(x = CUBE_SIZE*2; x >= 0; x--)
+ {
+ x = effect_telcstairs_do(x,val,delay);
+ }
+ }
+ else
+ {
+ for(x = 0; x < CUBE_SIZE*2; x++)
+ {
+ x = effect_telcstairs_do(x,val,delay);
+ }
+ }
+}
+
+void effect_wormsqueeze (int size, int axis, int direction, int iterations, int delay)
+{
+ int x, y, i,j,k, dx, dy;
+ int cube_size;
+ int origin = 0;
+
+ if (direction == -1)
+ origin = 7;
+
+ cube_size = 8-(size-1);
+
+ x = myrand()%cube_size;
+ y = myrand()%cube_size;
+
+ for (i=0; i<iterations; i++)
+ {
+ dx = ((myrand()%3)-1);
+ dy = ((myrand()%3)-1);
+
+ if ((x+dx) > 0 && (x+dx) < cube_size)
+ x += dx;
+
+ if ((y+dy) > 0 && (y+dy) < cube_size)
+ y += dy;
+
+ shift(axis, direction);
+
+
+ for (j=0; j<size;j++)
+ {
+ for (k=0; k<size;k++)
+ {
+ if (axis == AXIS_Z)
+ setvoxel(x+j,y+k,origin);
+
+ if (axis == AXIS_Y)
+ setvoxel(x+j,origin,y+k);
+
+ if (axis == AXIS_X)
+ setvoxel(origin,y+j,x+k);
+ }
+ }
+
+ delay_ms(delay);
+ }
+}
+
+void effect_pathmove (unsigned char *path, int length)
+{
+ int i,z;
+ unsigned char state;
+
+ for (i=(length-1);i>=1;i--)
+ {
+ for (z=0;z<8;z++)
+ {
+
+ state = getvoxel(((path[(i-1)]>>4) & 0x0f), (path[(i-1)] & 0x0f), z);
+ altervoxel(((path[i]>>4) & 0x0f), (path[i] & 0x0f), z, state);
+ }
+ }
+ for (i=0;i<8;i++)
+ clrvoxel(((path[0]>>4) & 0x0f), (path[0] & 0x0f),i);
+}
+
+
diff --git a/avr-test/src/effect.h b/avr-test/src/effect.h
new file mode 100644
index 0000000..3398082
--- /dev/null
+++ b/avr-test/src/effect.h
@@ -0,0 +1,54 @@
+#ifndef EFFECT_H
+#define EFFECT_H
+
+#include <avr/io.h>
+#include <avr/pgmspace.h>
+#include <stdlib.h>
+
+#include "cube.h"
+
+void effect_box_shrink_grow (int iterations, int rot, int flip, uint16_t delay);
+
+void effect_hollow_1 (int iterations, uint16_t delay);
+void effect_hollow_2 (int iterations, int corner, uint16_t delay);
+
+void sendvoxel_z (unsigned char x, unsigned char y, unsigned char z, int delay);
+void sendplane_rand_z (unsigned char z, int delay, int wait);
+void sendvoxels_rand_z (int iterations, int delay, int wait);
+void boingboing(uint16_t iterations, int delay, unsigned char mode, unsigned char drawmode);
+
+void effect_planboing (int plane, int speed);
+
+void effect_random_filler (int delay, int state);
+
+void effect_z_updown (int iterations, int delay);
+void effect_rain(int iterations);
+void effect_stringfly2(char * str);
+void effect_blinky2(void);
+void draw_positions_axis (char axis, unsigned char positions[64], int invert);
+void effect_axis_updown_randsuspend (char axis, int delay, int sleep, int invert);
+
+void effect_random_sparkle_flash (int iterations, int voxels, int delay);
+void effect_random_sparkle (void);
+
+void effect_box_woopwoop (int delay, int grow);
+void effect_telcstairs (int invert, int delay, int val);
+void effect_loadbar(int delay);
+
+void effect_boxside_randsend_parallel (char axis, int origin, int delay, int mode);
+void effect_smileyspin (int count, int delay, char bitmap);
+void effect_pathmove (unsigned char *path, int length);
+void effect_rand_patharound (int iterations, int delay);
+void effect_pathspiral (int iterations, int delay);
+void effect_path_text (int delay, char *str);
+void effect_path_bitmap (int delay, char bitmap, int iterations);
+void effect_wormsqueeze (int size, int axis, int direction, int iterations, int delay);
+
+void effect_z_updown (int iterations, int delay);
+void effect_z_updown_move (unsigned char positions[64], unsigned char destinations[64], char axis);
+
+
+
+
+#endif
+
diff --git a/avr-test/src/fuses.txt b/avr-test/src/fuses.txt
new file mode 100644
index 0000000..f24e5f5
--- /dev/null
+++ b/avr-test/src/fuses.txt
@@ -0,0 +1,6 @@
+
+lfuse: 0b11101111
+hfuse: 0b11001001
+
+
+
diff --git a/avr-test/src/lisence.txt b/avr-test/src/lisence.txt
new file mode 100644
index 0000000..812dab5
--- /dev/null
+++ b/avr-test/src/lisence.txt
@@ -0,0 +1,5 @@
+Created by Christian Moen (christian@lynet.no) and Ståle Kristoffersen (staalekb@ifi.uio.no) 2011.
+
+Lisence: http://creativecommons.org/licenses/by-nc-sa/3.0/
+
+Happy hacking!! :D
diff --git a/avr-test/src/main.c.old b/avr-test/src/main.c.old
new file mode 100644
index 0000000..be31861
--- /dev/null
+++ b/avr-test/src/main.c.old
@@ -0,0 +1,285 @@
+/*
+ * Code to controll an 8x8x8 ledcube using avr
+ * http://www.instructables.com/id/Led-Cube-8x8x8/
+ * See lisence.txt for lisence.
+ */
+#include "main.h"
+#include "effect.h"
+#include "launch_effect.h"
+#include "draw.h"
+
+// Main loop
+// the AVR enters this function at boot time
+int main (void)
+{
+
+ // This function initiates IO ports, timers, interrupts and
+ // serial communications
+ ioinit();
+
+ // This variable specifies which layer is currently being drawn by the
+ // cube interrupt routine. We assign a value to it to make sure it's not >7.
+ current_layer = 1;
+
+ int i;
+
+ // Boot wait
+ // This function serves 3 purposes
+ // 1) We delay starting up any interrupts, as drawing the cube causes a lot
+ // noise that can confuse the ISP programmer.
+ // 2) Listen for button press. One button means go into rs232 mode,
+ // The other means go into autonomous mode and start doing stuff.
+ // 3) Random seed. The bootwait function counts forever from 0 to 255.
+ // Whenever you press the button, this counter stops, and the number it
+ // stopped at is used as a random seed. This ensures true randomness at
+ // every boot. Without this (or some similar process) the cube would
+ // produce the same "random" sequence every time
+ i = bootwait();
+
+ // Enable interrupts
+ // This starts the routine that draws the cube content
+ sei();
+
+ // Result for bootwait() is 2:
+ // Go to rs232 mode. this function loops forever.
+ if (i == 2)
+ {
+ rs232();
+ }
+
+ // Result of bootwait() is something other than 2:
+ // Do awesome effects. Loop forever.
+ while (1)
+ {
+ // Show the effects in a predefined order
+ for (i=0; i<EFFECTS_TOTAL; i++)
+ launch_effect(i);
+
+ // Show the effects in a random order.
+ // Comment the two lines above and uncomment this
+ // if you want the effects in a random order.
+ //launch_effect(rand()%EFFECTS_TOTAL);
+ }
+
+}
+
+/*
+ * Multiplexer/framebuffer routine
+ * This function is called by an interrupt generated by timer 2.
+ * Every time it runs, it does the following:
+ * 1) Disable the output for the multiplexer array.
+ * 2) Turn of all layers.
+ * 3) Load the current layer from the cube buffer onto the
+ * multiplexer array.
+ * 4) Enable output from the multiplexer array.
+ * 5) Turn on the current layer.
+ * 6) Increment the current_layer variable, so the next layer is
+ * drawn the next time this function runs.
+*/
+
+ISR(TIMER2_COMP_vect)
+{
+ int i;
+
+ LAYER_SELECT = 0x00; // Turn all cathode layers off. (all transistors off)
+ OE_PORT |= OE_MASK; // Set OE high, disabling all outputs on latch array
+
+ // Loop through all 8 bytes of data in the current layer
+ // and latch it onto the cube.
+ for (i = 0; i < 8; i++)
+ {
+ // Set the data on the data-bus of the latch array.
+ PORTA = cube[current_layer][i];
+ // Increment the latch address chip, 74HC138, to create
+ // a rising edge (LOW to HIGH) on the current latch.
+ LATCH_ADDR = (LATCH_ADDR & LATCH_MASK_INV) | (LATCH_MASK & (i+1));
+ }
+
+ OE_PORT &= ~OE_MASK; // Set OE low, enabling outputs on the latch array
+ LAYER_SELECT = (0x01 << current_layer); // Transistor ON for current layer
+
+ // Increment the curren_layer counter so that the next layer is
+ // drawn the next time this function runs.
+ current_layer++;
+ // We want to count from 0-7, so set it to 0 when it reaches 8.
+ if (current_layer == 8)
+ current_layer = 0;
+}
+
+
+void ioinit (void)
+{
+ DDRA = 0xff; // DATA bus output
+ DDRB = 0xef; // Button on B4
+ DDRC = 0xff; // Layer select output
+ DDRD = 0xdf; // Button on D5
+
+
+ PORTA = 0x00; // Set data bus off
+ PORTC = 0x00; // Set layer select off
+ PORTB = 0x10; // Enable pull up on button.
+ PORTD = 0x20; // Enable pull up on button.
+
+
+ // Timer 2
+ // Frame buffer interrupt
+ // 14745600/128/11 = 10472.72 interrupts per second
+ // 10472.72/8 = 1309 frames per second
+ OCR2 = 10; // interrupt at counter = 10
+ TCCR2 |= (1 << CS20) | (1 << CS22); // Prescaler = 128.
+ TCCR2 |= (1 << WGM21); // CTC mode. Reset counter when OCR2 is reached.
+ TCNT2 = 0x00; // initial counter value = 0;
+ TIMSK |= (1 << OCIE2); // Enable CTC interrupt
+
+
+
+ // Initiate RS232
+ // USART Baud rate is defined in MYUBRR
+ UBRRH = MYUBRR >> 8;
+ UBRRL = MYUBRR;
+ // UCSRC - USART control register
+ // bit 7-6 sync/ascyn 00 = async, 01 = sync
+ // bit 5-4 parity 00 = disabled
+ // bit 3 stop bits 0 = 1 bit 1 = 2 bits
+ // bit 2-1 frame length 11 = 8
+ // bit 0 clock polarity = 0
+ UCSRC = 0b10000110;
+ // Enable RS232, tx and rx
+ UCSRB = (1<<RXEN)|(1<<TXEN);
+ UDR = 0x00; // send an empty byte to indicate powerup.
+
+
+}
+
+// Boot wait function
+// This function does 3 things:
+// 1) Delay startup of interrupt. I've had some problems with in circuit
+// serial programming when the cube was running. I guess switching all
+// those LEDs on and off generates some noise.
+// 2) Set a random random seed based on the delay between boot time and
+// the time you press a button.
+// 3) Select mode of operation, autonomous or rs232 controlled.
+unsigned int bootwait (void)
+{
+ // All the LED_PORT... code blinks the red and green status LEDs.
+
+ unsigned int x = 0;
+ LED_PORT |= LED_GREEN;
+ while (1)
+ {
+ x++; // increment x by one.
+ srand(x); // use counter x as random seed
+
+ delay_ms(1000);
+ LED_PORT &= ~LED_GREEN; // green off, red on
+ LED_PORT |= LED_RED;
+
+ // Listen for button presses and return with the
+ // apropriate number.
+ if (!(PIND & RS232_BTN))
+ return 2;
+
+ if (!(PINB & MAIN_BTN))
+ return 1;
+
+ delay_ms(1000);
+ LED_PORT &= ~LED_RED; // red off, green on
+ LED_PORT |= LED_GREEN;
+
+ // Same as above. I do it twise because there are two delays
+ // in this loop, used for the red and green led blinking..
+ if (!(PIND & RS232_BTN))
+ return 2;
+
+ if (!(PINB & MAIN_BTN))
+ return 1;
+ }
+}
+
+// Take input from a computer and load it onto the cube buffer
+void rs232(void)
+{
+ int tempval;
+ int x = 0;
+ int y = 0;
+ int escape = 0;
+
+ while (1)
+ {
+ // Switch state on red LED for debugging
+ // Should switch state every time the code
+ // is waiting for a byte to be received.
+ LED_PORT ^= LED_RED;
+
+ // Wait until a byte has been received
+ while ( !(UCSRA & (1<<RXC)) );
+
+ // Load the received byte from rs232 into a buffer.
+ tempval = UDR;
+
+ // Uncommet this to echo data back to the computer
+ // for debugging purposes.
+ //UDR = tempval;
+
+ // Every time the cube receives a 0xff byte,
+ // it goes into sync escape mode.
+ // if a 0x00 byte is then received, the x and y counters
+ // are reset to 0. This way the x and y counters are
+ // always the same on the computer and in the cube.
+ // To send an 0xff byte, you have to send it twice!
+
+ // Go into sync escape mode
+ if (tempval == 0xff)
+ {
+ // Wait for the next byte
+ while ( !(UCSRA & (1<<RXC)) );
+ // Get the next byte
+ tempval = UDR;
+
+ // Sync signal is received.
+ // Reset x and y counters to 0.
+ if (tempval == 0x00)
+ {
+ x = 0;
+ y = 0;
+ escape = 1;
+ }
+ // if no 0x00 byte is received, proceed with
+ // the byte we just received.
+ }
+
+ if (escape == 0)
+ {
+ // Load data into the current position in the buffer
+ fb[x][y] = tempval;
+
+ // Check if we have reached the limits of the buffer array.
+ if (y == 7)
+ {
+ if (x == 7)
+ {
+ // All data is loaded. Reset both counters
+ y = 0;
+ x = 0;
+ // Copy the data onto the cube.
+ tmp2cube();
+ } else
+ {
+ // A layer is loaded, reset y and increment x.
+ x++;
+ y = 0;
+ }
+ } else
+ {
+ // We are in the middle of loading a layer. increment y.
+ y++;
+ }
+
+ } else
+ {
+ escape = 0;
+ }
+ }
+}
+
+
diff --git a/avr-test/src/main.cpp b/avr-test/src/main.cpp
new file mode 100644
index 0000000..6f3d6ba
--- /dev/null
+++ b/avr-test/src/main.cpp
@@ -0,0 +1,508 @@
+/* (c) copyright N.C. 2011 */
+
+// ATMEL ATMEGA8
+//
+// +-\/-+
+// (RESET) PC6 1| |28 PC5 (ADC5/SCL)
+// (RXD) PD0 2| |27 PC4 (ADC4/SDA)
+// (TXD) PD1 3| |26 PC3 (ADC3)
+// (INT0) PD2 4| |25 PC2 (ADC2)
+// (INT1) PD3 5| |24 PC1 (ADC1)
+// (XCK/T0) PD4 6| |23 PC0 (ADC0)
+// VCC 7| |22 GND
+// GND 8| |21 AREF
+// (XTAL1/TOSC1) PB6 9| |20 AVCC
+// (XTAL2/TOSC2) PB7 10| |19 PB5 (SCK)
+// (T1) PD5 11| |18 PB4 (MISO)
+// (AIN0) PD6 12| |17 PB3 (MOSI/OC2)
+// (AIN1) PD7 13| |16 PB2 (SS/OC1B)
+// (ICP1) PB0 14| |15 PB1 (OC1A)
+// +----+
+
+extern "C" {
+#include <avr/io.h>
+#include <avr/interrupt.h>
+
+#include <stdlib.h> // rand
+}
+
+//char myrand()
+//{
+// static short rand = 0;
+// rand=(rand*109+89)%251;
+// return rand;
+//}
+
+int myrand() { return rand(); }
+
+#define CUBE_SIZE 8
+
+//#define AXIS_X 1
+//#define AXIS_Y 2
+//#define AXIS_Z 3
+
+volatile unsigned char cube[8][8];
+//volatile unsigned char current_layer = 0;
+extern volatile unsigned char current_layer;
+volatile bool in_wait = false;
+
+volatile unsigned char fb[CUBE_SIZE][CUBE_SIZE];
+/*****************************************************************************
+ * TIME MANAGEMENT
+ *****************************************************************************/
+
+#define F_CPU 8000000UL
+
+#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )
+#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() )
+#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() )
+
+// the prescaler is set so that timer0 ticks every 64 clock cycles, and the
+// the overflow handler is called every 256 ticks.
+#define MICROSECONDS_PER_TIMER0_OVERFLOW (clockCyclesToMicroseconds(64 * 256))
+
+// the whole number of milliseconds per timer0 overflow
+#define MILLIS_INC (MICROSECONDS_PER_TIMER0_OVERFLOW / 1000)
+
+// the fractional number of milliseconds per timer0 overflow. we shift right
+// by three to fit these numbers into a byte. (for the clock speeds we care
+// about - 8 and 16 MHz - this doesn't lose precision.)
+#define FRACT_INC ((MICROSECONDS_PER_TIMER0_OVERFLOW % 1000) >> 3)
+#define FRACT_MAX (1000 >> 3)
+
+//volatile uint32_t timer0_overflow_count = 0;
+volatile uint32_t timer0_millis = 0;
+//static uint8_t timer0_fract = 0;
+
+
+ISR(TIMER0_OVF_vect)
+{
+ // copy these to local variables so they can be stored in registers
+ // (volatile variables must be read from memory on every access)
+ uint32_t m = timer0_millis;
+ //uint8_t f = timer0_fract;
+ static uint8_t timer0_fract = 0;
+
+ m += MILLIS_INC;
+ //f += FRACT_INC;
+ timer0_fract += FRACT_INC;
+ //if (f >= FRACT_MAX) {
+ if (timer0_fract >= FRACT_MAX) {
+ //f -= FRACT_MAX;
+ timer0_fract -= FRACT_MAX;
+ ++m;
+ }
+
+ //timer0_fract = f;
+ timer0_millis = m;
+ //timer0_overflow_count++;
+
+//static uint32_t last_time = 0;
+ //if (timer0_overflow_count & 0x1)
+ //if (m - last_time >= 5) {
+ //debounce_keys(); // called nearly each 2ms (0,002048s)
+ //last_time = m;
+ //}
+}
+
+/*
+inline uint32_t millis()
+{
+ uint32_t m;
+ uint8_t oldSREG = SREG;
+
+ // disable interrupts while we read timer0_millis or we might get an
+ // inconsistent value (e.g. in the middle of a write to timer0_millis)
+ cli();
+ m = timer0_millis;
+ SREG = oldSREG;
+
+ return m;
+}
+*/
+
+inline uint32_t millis()
+{
+ return timer0_millis;
+}
+
+void delay(uint32_t ms)
+{
+ in_wait = true;
+ uint32_t time1 = millis();
+ while ((millis()) - time1 < ms);
+ in_wait = false;
+}
+//void delay_ms(uint16_t x)
+//{
+// in_wait = true;
+// uint8_t y, z;
+// for ( ; x > 0 ; x--){
+// for ( y = 0 ; y < 90 ; y++){
+// for ( z = 0 ; z < 6 ; z++){
+// asm volatile ("nop");
+// }
+// }
+// }
+// in_wait = false;
+//}
+
+
+/*****************************************************************************
+ * ACCESSORS
+ *****************************************************************************/
+
+//unsigned char inrange(int x, int y, int z)
+//{
+// if (x >= 0 && x < CUBE_SIZE && y >= 0 && y < CUBE_SIZE && z >= 0 && z < CUBE_SIZE)
+// {
+// return 1;
+// } else
+// {
+// // One of the coordinates was outside the cube.
+// return 0;
+// }
+//}
+
+//bool get_led(unsigned char x, unsigned char y, unsigned char z)
+//{
+// /*
+// assert(x >= 0 && x <= 7);
+// assert(y >= 0 && y <= 7);
+// assert(z >= 0 && z <= 7);
+// */
+//
+// if (inrange(x, y, z)) {
+// return cube[y][z] & (1 << x);
+// }
+//
+// return false;
+//}
+
+//void set_led(unsigned char x, unsigned char y, unsigned char z, bool on)
+//{
+//
+// if (!inrange(x, y, z)) {
+// return;
+// }
+//
+// /*
+// assert(x >= 0 && x <= 7);
+// assert(y >= 0 && y <= 7);
+// assert(z >= 0 && z <= 7);
+// */
+//
+// if (on) {
+// cube[y][z] |= ((unsigned char)1) << x;
+// }
+// else {
+// cube[y][z] &= ~(((unsigned char)1) << x);
+// }
+//}
+
+void clear_led()
+{
+ for (unsigned char z = 0; z < 8; ++z) {
+ for (unsigned char y = 0; y < 8; ++y) {
+ cube[y][z] = 0;
+ }
+ }
+}
+
+/*****************************************************************************
+ * RENDER
+ *****************************************************************************/
+
+//ISR(TIMER2_COMP_vect)
+//{
+// //if (!in_wait) return;
+// PORTC &= ~0x28; // layer and latch low
+// unsigned char current_layer_ = current_layer;
+//
+// for (char j = 0; j < 8; ++j) {
+// //for (char j = 0; j < 4; ++j) {
+// unsigned char val = cube[7-j][current_layer_];
+// //unsigned char val2 = cube[3-j][current_layer_];
+// for (char i = 0; i < 8; ++i/*, val >>= 1*/) {
+// PORTC &= ~0x10;
+// //PORTD = (PORTD & ~0x80) | ((val2 << (7-i)) & 0x80);
+// PORTB = (PORTB & ~0x01) | ((val >> i) & 0x01);
+// //PORTB |= 0x01;
+//
+// //PORTD |= 0x80;
+// //PORTD = (PORTD & ~0x40) | (((val << (7-i)) & 0x80) >> 1);
+// PORTC |= 0x10;
+// }
+// }
+//
+// PORTC = (PORTC & ~0x07) | current_layer_;
+// ++current_layer_;
+// current_layer = current_layer_ & 0x07;
+//
+// PORTC |= 0x28; // layer and latch high
+//}
+
+ISR(TIMER2_COMP_vect)
+{
+ //if (!in_wait) return;
+ PORTC &= ~0x28; // layer and latch low
+ unsigned char current_layer_ = current_layer;
+
+ for (unsigned char j = 7; j < 255; --j) {
+ //for (char j = 0; j < 4; ++j) {
+ unsigned char val = cube[j][current_layer_];
+ PORTC &= ~0x10;
+ PORTB = (PORTB & ~0x01) | ((val ) & 0x01);
+ PORTC |= 0x10;
+ PORTC &= ~0x10;
+ PORTB = (PORTB & ~0x01) | ((val >> 1) & 0x01);
+ PORTC |= 0x10;
+ PORTC &= ~0x10;
+ PORTB = (PORTB & ~0x01) | ((val >> 2) & 0x01);
+ PORTC |= 0x10;
+ PORTC &= ~0x10;
+ PORTB = (PORTB & ~0x01) | ((val >> 3) & 0x01);
+ PORTC |= 0x10;
+ PORTC &= ~0x10;
+ PORTB = (PORTB & ~0x01) | ((val >> 4) & 0x01);
+ PORTC |= 0x10;
+ PORTC &= ~0x10;
+ PORTB = (PORTB & ~0x01) | ((val >> 5) & 0x01);
+ PORTC |= 0x10;
+ PORTC &= ~0x10;
+ PORTB = (PORTB & ~0x01) | ((val >> 6) & 0x01);
+ PORTC |= 0x10;
+ PORTC &= ~0x10;
+ PORTB = (PORTB & ~0x01) | ((val >> 7) & 0x01);
+ //PORTD = val;
+ PORTC |= 0x10;
+ }
+
+ PORTC = (PORTC & ~0x07) | current_layer_ | 0x28;
+ ++current_layer_;
+ if (current_layer_ > 7) current_layer_ = 0;
+ //current_layer = current_layer_ & 0x07;
+ current_layer = current_layer_;
+
+ //PORTC |= 0x28; // layer and latch high
+}
+
+
+
+//void draw_positions_axis (char axis, unsigned char positions[64], int invert)
+//{
+// int x, y, p;
+//
+// //fill(0x00);
+// clear_led();
+//
+// for (x=0; x<8; x++)
+// {
+// for (y=0; y<8; y++)
+// {
+// if (invert)
+// {
+// p = (7-positions[(x*8)+y]);
+// } else
+// {
+// p = positions[(x*8)+y];
+// }
+//
+// if (axis == AXIS_Z)
+// //setvoxel(x,y,p);
+// set_led(x, y, p, true);
+//
+// if (axis == AXIS_Y)
+// //setvoxel(x,p,y);
+// set_led(x,p,y, true);
+//
+// if (axis == AXIS_X)
+// set_led(p,y,x, true);
+// }
+// }
+//
+//}
+
+
+
+
+//void effect_boxside_randsend_parallel (char axis, int origin, int delay, int mode)
+//{
+// int i;
+// int done;
+// unsigned char cubepos[64];
+// unsigned char pos[64];
+// int notdone = 1;
+// int notdone2 = 1;
+// int sent = 0;
+//
+// for (i=0;i<64;i++)
+// {
+// pos[i] = 0;
+// }
+//
+// while (notdone)
+// {
+// if (mode == 1)
+// {
+// notdone2 = 1;
+// while (notdone2 && sent<64)
+// {
+// i = myrand()%64;
+// if (pos[i] == 0)
+// {
+// sent++;
+// pos[i] += 1;
+// notdone2 = 0;
+// }
+// }
+// } else if (mode == 2)
+// {
+// if (sent<64)
+// {
+// pos[sent] += 1;
+// sent++;
+// }
+// }
+//
+// done = 0;
+// for (i=0;i<64;i++)
+// {
+// if (pos[i] > 0 && pos[i] <7)
+// {
+// pos[i] += 1;
+// }
+//
+// if (pos[i] == 7)
+// done++;
+// }
+//
+// if (done == 64)
+// notdone = 0;
+//
+// for (i=0;i<64;i++)
+// {
+// if (origin == 0)
+// {
+// cubepos[i] = pos[i];
+// } else
+// {
+// cubepos[i] = (7-pos[i]);
+// }
+// }
+//
+//
+// delay_ms(delay);
+// draw_positions_axis(axis,cubepos,0);
+//
+// }
+//
+//}
+
+
+
+/*****************************************************************************
+ * MAIN
+ *****************************************************************************/
+#include "main.h"
+#include "effect.h"
+#include "draw.h"
+
+int main()
+{
+ /*
+ * =======================================================================
+ * Initialisation
+ * =======================================================================
+ */
+
+ //*** init time management
+ TCNT0 = 0; // init timer count to 0
+ TCCR0 |= 0x03; // prescaler: 64
+ TIMSK |= 0x01; // enable timer 0 overflow interrupt
+
+ // Timer 2
+ // Frame buffer interrupt
+ // 14745600/128/11 = 10472.72 interrupts per second
+ // 10472.72/8 = 1309 frames per second
+ OCR2 = 11; // interrupt at counter = 10
+ TCCR2 |= (1 << CS20) | (0 << CS21) | (1 << CS22); // Prescaler = 128.
+ TCCR2 |= (1 << WGM21); // CTC mode. Reset counter when OCR2 is reached.
+ TCNT2 = 0x00; // initial counter value = 0;
+ TIMSK |= (1 << OCIE2); // Enable CTC interrupt
+
+ PORTD = 0;
+ PORTB = 0;
+ PORTC = 0;
+ DDRD = 0xff;
+ DDRB = 0xff;
+ DDRC = 0xff;
+
+ //*** set interupts
+ sei();
+
+ /*
+ * =======================================================================
+ * MAIN LOOP
+ * =======================================================================
+ */
+
+ for (;;) {
+
+ //clear_led();
+ //delay_ms(1000);
+ for (unsigned char z = 0; z < 8; ++z) {
+ for (unsigned char y = 0; y < 8; ++y) {
+ cube[y][z] = 0xFF;
+ }
+ }
+ //continue;
+ delay(1000);
+
+ // Show the effects in a predefined order
+ //for (char i=0; i<EFFECTS_TOTAL; i++)
+ //launch_effect(i);
+ sendvoxels_rand_z(20,220,2000);
+ effect_rain(100);
+ effect_random_filler(5,1);
+ effect_z_updown(20,1000);
+ effect_wormsqueeze (2, AXIS_Z, -1, 100, 1000);
+ effect_blinky2();
+
+
+ // Show the effects in a random order.
+ // Comment the two lines above and uncomment this
+ // if you want the effects in a random order.
+ //launch_effect(rand()%EFFECTS_TOTAL);
+
+ for (char i = 0; i < 10; ++i) {
+ effect_boxside_randsend_parallel (AXIS_X, 0, 150, 1);
+ effect_boxside_randsend_parallel (AXIS_X, 1, 150, 1);
+ effect_boxside_randsend_parallel (AXIS_Y, 0, 150, 1);
+ effect_boxside_randsend_parallel (AXIS_Y, 1, 150, 1);
+ effect_boxside_randsend_parallel (AXIS_Z, 0, 150, 1);
+ effect_boxside_randsend_parallel (AXIS_Z, 1, 150, 1);
+ }
+
+ continue;
+
+ //return;
+ for (char z = 0; z < 8; ++z) {
+ for (char y = 0; y < 8; ++y) {
+ for (char x = 0; x < 8; ++x) {
+ //set_led(x, y, z, true);
+ delay(5);
+ delay(100);
+ //delay(500);
+ //delay(1000);
+ //delay_ms(1000);
+ }
+ }
+ }
+
+ //delay(1000);
+ //PORTB ^= 0x01;
+ }
+
+ return 0; // normally never return, just to be complient with c99 standard
+}
diff --git a/avr-test/src/main.h b/avr-test/src/main.h
new file mode 100644
index 0000000..0a755f7
--- /dev/null
+++ b/avr-test/src/main.h
@@ -0,0 +1,45 @@
+#ifndef MAIN_H
+#define MAIN_H
+
+#include <avr/io.h>
+#include <avr/pgmspace.h>
+#include <avr/interrupt.h>
+#include <stdlib.h>
+
+#include "cube.h"
+
+// Define USART stuff
+#define FOSC 14745600
+#define BAUD 38400
+#define MYUBRR (((((FOSC * 10) / (16L * BAUD)) + 5) / 10) - 1)
+
+#define DATA_BUS PORTA
+#define LAYER_SELECT PORTC
+#define LATCH_ADDR PORTB
+#define LATCH_MASK 0x07
+#define LATCH_MASK_INV 0xf8
+#define OE_PORT PORTB
+#define OE_MASK 0x08
+
+// Red led on D2
+#define LED_RED 0x04
+// Green led D3
+#define LED_GREEN 0x08
+// Program led on D4
+#define LED_PGM 0x10;
+// Leds connected to port D
+#define LED_PORT PORTD
+// Rs232 button on D5
+#define RS232_BTN 0x20
+// Main button on B4
+#define MAIN_BTN 0x10
+
+void ioinit (void);
+void bootmsg (void);
+
+volatile unsigned char current_layer;
+volatile unsigned char pgm_mode;
+void rs232(void);
+unsigned int bootwait (void);
+#endif
+
diff --git a/avr-test/tags b/avr-test/tags
new file mode 100644
index 0000000..94663e7
--- /dev/null
+++ b/avr-test/tags
@@ -0,0 +1,150 @@
+!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
+!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
+!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/
+!_TAG_PROGRAM_NAME Exuberant Ctags //
+!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/
+!_TAG_PROGRAM_VERSION 5.9~svn20110310 //
+-mcu Makefile /^ avr-size --mcu=$(MCU_TARGET) -C $(PRG).elf$/;" m
+AXIS_X src/cube.h 27;" d
+AXIS_Y src/cube.h 28;" d
+AXIS_Z src/cube.h 29;" d
+BAUD src/main.h 13;" d
+CC Makefile /^CC = avr-gcc$/;" m
+CUBE_BYTES src/cube.h 8;" d
+CUBE_H src/cube.h 2;" d
+CUBE_SIZE src/cube.h 7;" d
+CUBE_SIZE src/main.cpp 30;" d file:
+CXX Makefile /^CXX = avr-g++$/;" m
+DATA_BUS src/main.h 16;" d
+DEFS Makefile /^DEFS =$/;" m
+DFLAGS Makefile /^override LDFLAGS = -Wl,-Map,$(PRG).map --relax$/;" m
+EEMEM src/font.cpp /^volatile const unsigned char bitmaps[6][8] EEMEM = {$/;" v
+EEMEM src/font.cpp /^volatile const unsigned char font[455] EEMEM = {$/;" v
+EXTRA_CLEAN_FILES Makefile /^EXTRA_CLEAN_FILES = *.hex *.bin *.srec$/;" m
+FIG2DEV Makefile /^FIG2DEV = fig2dev$/;" m
+FLAGS Makefile /^override CFLAGS = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS) #-fno-exceptions -fno-rtti$/;" m
+FOSC src/main.h 12;" d
+FRACT_INC src/main.cpp 62;" d file:
+FRACT_MAX src/main.cpp 63;" d file:
+F_CPU src/main.cpp 46;" d file:
+GOL_CREATE_MAX /home/calendros/work/ledcube/avr/src/gameoflife.cpp 9;" d file:
+GOL_CREATE_MIN /home/calendros/work/ledcube/avr/src/gameoflife.cpp 8;" d file:
+GOL_TERMINATE_CROWDED /home/calendros/work/ledcube/avr/src/gameoflife.cpp 12;" d file:
+GOL_TERMINATE_LONELY /home/calendros/work/ledcube/avr/src/gameoflife.cpp 11;" d file:
+GOL_WRAP /home/calendros/work/ledcube/avr/src/gameoflife.cpp 18;" d file:
+GOL_X /home/calendros/work/ledcube/avr/src/gameoflife.cpp 14;" d file:
+GOL_Y /home/calendros/work/ledcube/avr/src/gameoflife.cpp 15;" d file:
+GOL_Z /home/calendros/work/ledcube/avr/src/gameoflife.cpp 16;" d file:
+ISR src/main.cpp /^ISR(TIMER0_OVF_vect)$/;" f signature:(TIMER0_OVF_vect)
+ISR src/main.cpp /^ISR(TIMER2_COMP_vect)$/;" f signature:(TIMER2_COMP_vect)
+LATCH_ADDR src/main.h 18;" d
+LATCH_MASK src/main.h 19;" d
+LATCH_MASK_INV src/main.h 20;" d
+LAYER_SELECT src/main.h 17;" d
+LED_GREEN src/main.h 27;" d
+LED_PGM src/main.h 29;" d
+LED_PORT src/main.h 31;" d
+LED_RED src/main.h 25;" d
+LIBS Makefile /^LIBS =$/;" m
+MAIN_BTN src/main.h 35;" d
+MAIN_H src/main.h 2;" d
+MCU_TARGET Makefile /^MCU_TARGET = atmega8$/;" m
+MICROSECONDS_PER_TIMER0_OVERFLOW src/main.cpp 54;" d file:
+MILLIS_INC src/main.cpp 57;" d file:
+MYUBRR src/main.h 14;" d
+OBJ Makefile /^OBJ = main.o draw.o effect.o font.o launch_effect.o$/;" m
+OBJCOPY Makefile /^OBJCOPY = avr-objcopy$/;" m
+OBJDUMP Makefile /^OBJDUMP = avr-objdump$/;" m
+OE_MASK src/main.h 22;" d
+OE_PORT src/main.h 21;" d
+OPTIMIZE Makefile /^OPTIMIZE = -Os$/;" m
+PRG Makefile /^PRG = ledcube$/;" m
+PROGMEM src/font.cpp /^const unsigned char paths[44] PROGMEM = {0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00,0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x67,0x57,0x47,0x37,0x27,0x17,$/;" v
+RS232_BTN src/main.h 33;" d
+altervoxel src/draw.cpp /^void altervoxel(int x, int y, int z, int state)$/;" f signature:(int x, int y, int z, int state)
+argorder src/draw.cpp /^void argorder(int ix1, int ix2, int *ox1, int *ox2)$/;" f signature:(int ix1, int ix2, int *ox1, int *ox2)
+boingboing /home/calendros/work/ledcube/avr/src/effect.cpp /^void boingboing(uint16_t iterations, int delay, unsigned char mode, unsigned char drawmode)$/;" f signature:(uint16_t iterations, int delay, unsigned char mode, unsigned char drawmode)
+bootmsg src/main.h /^void bootmsg (void);$/;" p signature:(void)
+bootwait src/main.h /^unsigned int bootwait (void);$/;" p signature:(void)
+box_filled src/draw.cpp /^void box_filled(int x1, int y1, int z1, int x2, int y2, int z2)$/;" f signature:(int x1, int y1, int z1, int x2, int y2, int z2)
+box_walls src/draw.cpp /^void box_walls(int x1, int y1, int z1, int x2, int y2, int z2)$/;" f signature:(int x1, int y1, int z1, int x2, int y2, int z2)
+box_wireframe src/draw.cpp /^void box_wireframe(int x1, int y1, int z1, int x2, int y2, int z2)$/;" f signature:(int x1, int y1, int z1, int x2, int y2, int z2)
+byteline src/draw.cpp /^char byteline (int start, int end)$/;" f signature:(int start, int end)
+clear_led src/main.cpp /^void clear_led()$/;" f signature:()
+clockCyclesPerMicrosecond src/main.cpp 48;" d file:
+clockCyclesToMicroseconds src/main.cpp 49;" d file:
+clrplane src/draw.cpp /^void clrplane (char axis, unsigned char i)$/;" f signature:(char axis, unsigned char i)
+clrplane_x src/draw.cpp /^void clrplane_x (int x)$/;" f signature:(int x)
+clrplane_y src/draw.cpp /^void clrplane_y (int y)$/;" f signature:(int y)
+clrplane_z src/draw.cpp /^void clrplane_z (int z)$/;" f signature:(int z)
+clrvoxel src/draw.cpp /^void clrvoxel(int x, int y, int z)$/;" f signature:(int x, int y, int z)
+cube src/cube.h /^volatile unsigned char cube[CUBE_SIZE][CUBE_SIZE];$/;" v
+current_layer src/main.h /^volatile unsigned char current_layer;$/;" v
+delay src/main.cpp /^void delay(uint32_t ms)$/;" f signature:(uint32_t ms)
+delay_ms src/draw.cpp /^void delay_ms(uint16_t x)$/;" f signature:(uint16_t x)
+draw_positions_axis /home/calendros/work/ledcube/avr/src/effect.cpp /^void draw_positions_axis (char axis, unsigned char positions[64], int invert)$/;" f signature:(char axis, unsigned char positions[64], int invert)
+effect_axis_updown_randsuspend /home/calendros/work/ledcube/avr/src/effect.cpp /^void effect_axis_updown_randsuspend (char axis, int delay, int sleep, int invert)$/;" f signature:(char axis, int delay, int sleep, int invert)
+effect_blinky2 /home/calendros/work/ledcube/avr/src/effect.cpp /^void effect_blinky2()$/;" f signature:()
+effect_box_shrink_grow /home/calendros/work/ledcube/avr/src/effect.cpp /^void effect_box_shrink_grow (int iterations, int rot, int flip, uint16_t delay)$/;" f signature:(int iterations, int rot, int flip, uint16_t delay)
+effect_box_woopwoop /home/calendros/work/ledcube/avr/src/effect.cpp /^void effect_box_woopwoop (int delay, int grow)$/;" f signature:(int delay, int grow)
+effect_boxside_randsend_parallel /home/calendros/work/ledcube/avr/src/effect.cpp /^void effect_boxside_randsend_parallel (char axis, int origin, int delay, int mode)$/;" f signature:(char axis, int origin, int delay, int mode)
+effect_loadbar /home/calendros/work/ledcube/avr/src/effect.cpp /^void effect_loadbar(int delay)$/;" f signature:(int delay)
+effect_path_bitmap /home/calendros/work/ledcube/avr/src/effect.cpp /^void effect_path_bitmap (int delay, char bitmap, int iterations)$/;" f signature:(int delay, char bitmap, int iterations)
+effect_path_text /home/calendros/work/ledcube/avr/src/effect.cpp /^void effect_path_text (int delay, char *str)$/;" f signature:(int delay, char *str)
+effect_pathmove /home/calendros/work/ledcube/avr/src/effect.cpp /^void effect_pathmove (unsigned char *path, int length)$/;" f signature:(unsigned char *path, int length)
+effect_pathspiral /home/calendros/work/ledcube/avr/src/effect.cpp /^void effect_pathspiral (int iterations, int delay)$/;" f signature:(int iterations, int delay)
+effect_planboing /home/calendros/work/ledcube/avr/src/effect.cpp /^void effect_planboing (int plane, int speed)$/;" f signature:(int plane, int speed)
+effect_rain /home/calendros/work/ledcube/avr/src/effect.cpp /^void effect_rain (int iterations)$/;" f signature:(int iterations)
+effect_rand_patharound /home/calendros/work/ledcube/avr/src/effect.cpp /^void effect_rand_patharound (int iterations, int delay)$/;" f signature:(int iterations, int delay)
+effect_random_filler /home/calendros/work/ledcube/avr/src/effect.cpp /^void effect_random_filler (int delay, int state)$/;" f signature:(int delay, int state)
+effect_random_sparkle /home/calendros/work/ledcube/avr/src/effect.cpp /^void effect_random_sparkle (void)$/;" f signature:(void)
+effect_random_sparkle_flash /home/calendros/work/ledcube/avr/src/effect.cpp /^void effect_random_sparkle_flash (int iterations, int voxels, int delay)$/;" f signature:(int iterations, int voxels, int delay)
+effect_smileyspin /home/calendros/work/ledcube/avr/src/effect.cpp /^void effect_smileyspin (int count, int delay, char bitmap)$/;" f signature:(int count, int delay, char bitmap)
+effect_stringfly2 /home/calendros/work/ledcube/avr/src/effect.cpp /^void effect_stringfly2(char * str)$/;" f signature:(char * str)
+effect_telcstairs /home/calendros/work/ledcube/avr/src/effect.cpp /^void effect_telcstairs (int invert, int delay, int val)$/;" f signature:(int invert, int delay, int val)
+effect_telcstairs_do /home/calendros/work/ledcube/avr/src/effect.cpp /^int effect_telcstairs_do(int x, int val, int delay)$/;" f signature:(int x, int val, int delay)
+effect_test /home/calendros/work/ledcube/avr/src/effect.cpp /^void effect_test (void)$/;" f signature:(void)
+effect_wormsqueeze /home/calendros/work/ledcube/avr/src/effect.cpp /^void effect_wormsqueeze (int size, int axis, int direction, int iterations, int delay)$/;" f signature:(int size, int axis, int direction, int iterations, int delay)
+effect_z_updown /home/calendros/work/ledcube/avr/src/effect.cpp /^void effect_z_updown (int iterations, int delay)$/;" f signature:(int iterations, int delay)
+effect_z_updown_move /home/calendros/work/ledcube/avr/src/effect.cpp /^void effect_z_updown_move (unsigned char positions[64], unsigned char destinations[64], char axis)$/;" f signature:(unsigned char positions[64], unsigned char destinations[64], char axis)
+fb src/cube.h /^volatile unsigned char fb[CUBE_SIZE][CUBE_SIZE];$/;" v
+fill src/draw.cpp /^void fill (unsigned char pattern)$/;" f signature:(unsigned char pattern)
+flipbyte src/draw.cpp /^char flipbyte (char byte)$/;" f signature:(char byte)
+flpvoxel src/draw.cpp /^void flpvoxel(int x, int y, int z)$/;" f signature:(int x, int y, int z)
+font_getbitmap src/font.cpp /^void font_getbitmap (char bitmap, unsigned char dst[8])$/;" f signature:(char bitmap, unsigned char dst[8])
+font_getbitmappixel src/font.cpp /^unsigned char font_getbitmappixel ( char bitmap, char x, char y)$/;" f signature:( char bitmap, char x, char y)
+font_getchar src/font.cpp /^void font_getchar (char chr, unsigned char dst[5])$/;" f signature:(char chr, unsigned char dst[5])
+font_getpath src/font.cpp /^void font_getpath (unsigned char path, unsigned char *destination, int length)$/;" f signature:(unsigned char path, unsigned char *destination, int length)
+getvoxel src/draw.cpp /^unsigned char getvoxel(int x, int y, int z)$/;" f signature:(int x, int y, int z)
+gol_count_changes /home/calendros/work/ledcube/avr/src/gameoflife.cpp /^int gol_count_changes (void)$/;" f signature:(void)
+gol_count_neighbors /home/calendros/work/ledcube/avr/src/gameoflife.cpp /^unsigned char gol_count_neighbors (int x, int y, int z)$/;" f signature:(int x, int y, int z)
+gol_nextgen /home/calendros/work/ledcube/avr/src/gameoflife.cpp /^void gol_nextgen (void)$/;" f signature:(void)
+gol_play /home/calendros/work/ledcube/avr/src/gameoflife.cpp /^void gol_play (int iterations, uint16_t delay)$/;" f signature:(int iterations, uint16_t delay)
+in_wait src/main.cpp /^volatile bool in_wait = false;$/;" v
+inrange src/draw.cpp /^unsigned char inrange(int x, int y, int z)$/;" f signature:(int x, int y, int z)
+ioinit src/main.h /^void ioinit (void);$/;" p signature:(void)
+launch_effect src/launch_effect.cpp /^void launch_effect (int effect)$/;" f signature:(int effect)
+line src/draw.cpp /^void line(int x1, int y1, int z1, int x2, int y2, int z2)$/;" f signature:(int x1, int y1, int z1, int x2, int y2, int z2)
+main src/main.cpp /^int main()$/;" f signature:()
+microsecondsToClockCycles src/main.cpp 50;" d file:
+millis src/main.cpp /^inline uint32_t millis()$/;" f signature:()
+mirror_x src/draw.cpp /^void mirror_x (void)$/;" f signature:(void)
+mirror_y src/draw.cpp /^void mirror_y (void)$/;" f signature:(void)
+mirror_z src/draw.cpp /^void mirror_z (void)$/;" f signature:(void)
+pgm_mode src/main.h /^volatile unsigned char pgm_mode;$/;" v
+rand src/main.cpp /^int rand(void);$/;" p file: signature:(void)
+rs232 src/main.h /^void rs232(void);$/;" p signature:(void)
+sendplane_rand_z /home/calendros/work/ledcube/avr/src/effect.cpp /^void sendplane_rand_z (unsigned char z, int delay, int wait)$/;" f signature:(unsigned char z, int delay, int wait)
+sendvoxel_z /home/calendros/work/ledcube/avr/src/effect.cpp /^void sendvoxel_z (unsigned char x, unsigned char y, unsigned char z, int delay)$/;" f signature:(unsigned char x, unsigned char y, unsigned char z, int delay)
+sendvoxels_rand_z /home/calendros/work/ledcube/avr/src/effect.cpp /^void sendvoxels_rand_z (int iterations, int delay, int wait)$/;" f signature:(int iterations, int delay, int wait)
+setplane src/draw.cpp /^void setplane (char axis, unsigned char i)$/;" f signature:(char axis, unsigned char i)
+setplane_x src/draw.cpp /^void setplane_x (int x)$/;" f signature:(int x)
+setplane_y src/draw.cpp /^void setplane_y (int y)$/;" f signature:(int y)
+setplane_z src/draw.cpp /^void setplane_z (int z)$/;" f signature:(int z)
+setvoxel src/draw.cpp /^void setvoxel(int x, int y, int z)$/;" f signature:(int x, int y, int z)
+shift src/draw.cpp /^void shift (char axis, int direction)$/;" f signature:(char axis, int direction)
+timer0_millis src/main.cpp /^volatile uint32_t timer0_millis = 0;$/;" v
+tmp2cube src/draw.cpp /^void tmp2cube (void)$/;" f signature:(void)
+tmpclrvoxel src/draw.cpp /^void tmpclrvoxel(int x, int y, int z)$/;" f signature:(int x, int y, int z)
+tmpfill src/draw.cpp /^void tmpfill (unsigned char pattern)$/;" f signature:(unsigned char pattern)
+tmpsetvoxel src/draw.cpp /^void tmpsetvoxel(int x, int y, int z)$/;" f signature:(int x, int y, int z)