Index: Beep/Makefile
===================================================================
--- Beep/Makefile	(revision 26d7f341f56638355ccf76f8cdae59dc2a644bfb)
+++ Beep/Makefile	(revision 26d7f341f56638355ccf76f8cdae59dc2a644bfb)
@@ -0,0 +1,25 @@
+#Set vars
+COMPILE = avr-gcc -Wall -Os -std=c99 -mmcu=atmega8535 -DF_CPU=4000000
+
+#Rules
+blinkdel.hex: blinkdel.bin
+	avr-objcopy -j .text -j .data -O ihex blinkdel.bin blinkdel.hex
+
+blinkdel.bin: main.o
+	$(COMPILE) main.o -o blinkdel.bin
+
+main.o: main.c
+	$(COMPILE) -c main.c -o main.o
+
+#Generic rules
+.S.o:
+	$(COMPILE) -x assembler-with-cpp -c $< -o $@
+
+.c.o:
+	$(COMPILE) -std=c99 -c $< -o $@
+
+flash:
+	avrdude -c usbasp -p atmega8535 -Uflash:w:blinkdel.hex
+
+clean:
+	rm *.bin *.o *.hex
Index: Beep/blinkdel.hex
===================================================================
--- Beep/blinkdel.hex	(revision 26d7f341f56638355ccf76f8cdae59dc2a644bfb)
+++ Beep/blinkdel.hex	(revision 26d7f341f56638355ccf76f8cdae59dc2a644bfb)
@@ -0,0 +1,98 @@
+:10000000FAC014C113C112C111C110C10FC10EC178
+:100010000DC10DC10BC10AC109C108C107C106C18B
+:1000200005C104C103C102C101C1280801000023A8
+:100030000401000024040100002604010000000463
+:100040000000002404010000230401000021040139
+:10005000000000040000002104010000240401004D
+:100060000028040100000004000000260401000034
+:100070002404010000230401000000080000002403
+:1000800004010000260801000028080100002408DF
+:10009000010000210701000000010000002108010B
+:1000A00000000008000000260C01000029040100E7
+:1000B000002D080100002B040100002904010000AC
+:1000C00028080100000004000000240401000028AA
+:1000D000080100002604010000240401000023049C
+:1000E00001000000080000002404010000260801AF
+:1000F0000000280801000024080100002107010079
+:1001000000000100000021080100000008000000BC
+:100110002810010000241001000026100100002317
+:1001200010010000241001000021100100001F1028
+:10013000010000201001000000080000002810014C
+:10014000000024100100002610010000231001000F
+:100150000024080100002608010000000000000043
+:100160001804010000240401000018040100002408
+:100170000401000018040100002404010000180418
+:1001800001000024040100001F040100002B0401F1
+:1001900000001F040100002B040100001F040100E7
+:1001A000002B040100001F040100002B04010000CB
+:1001B0001C0401000028040100001C0401000028A8
+:1001C00004010000170401000023040100001704CB
+:1001D00001000023040100001804010000240401B0
+:1001E00000001804010000240401000018100100A0
+:1001F00000000000000011241FBECFE5D2E0DEBFEA
+:10020000CDBF10E0A0E6B0E0E2EDF5E002C0059061
+:100210000D92A039B107D9F710E0A0E9B0E001C014
+:100220001D92A239B107E1F719D0D1C1E9CE1F92D1
+:100230000F920FB60F9211248F939F93809190008D
+:1002400090919100019690939100809390009F91DE
+:100250008F910F900FBE0F901F9018952F923F9285
+:100260004F925F926F927F928F929F92AF92BF92C6
+:10027000CF92DF92EF92FF920F931F93DF93CF9372
+:10028000CDB7DEB729970FB6F894DEBF0FBECDBF4E
+:100290002FE088E190E00FB6F894A89581BD0FBEDD
+:1002A00021BD85E083BF81E089BF1092910010924B
+:1002B000900080E48FBD88E08EBD8EE590E09BBD10
+:1002C0008ABD88E185BD12BC8FEF87BB789488BB5F
+:1002D0001F821E821D821C824424552432018824E0
+:1002E00099245401EE24FF248701DD2440E028E214
+:1002F0002B831A8261E0262E312C58E1C52E1982FB
+:1003000081E090E099878887A895809190009091EE
+:100310009100892BC9F380919000909191000197F1
+:100320009093910080939000E414F504060517055E
+:10033000BCF1EE81FF81EE0FFF1FEE0FFF1FAE81BC
+:10034000BF81EA0FFB1FE05AFE4FB081BB832481BF
+:100350002A83228033809181AE81BF811196BF8331
+:10036000AE8327013801490E511C611C711C2114F8
+:10037000310419F08EB5846002C08EB58B7F8EBDBE
+:10038000BA81BB2361F4992351F41F821E8221E0BC
+:10039000422E512C612C712CEE24FF248701DD2488
+:1003A000D394E3E02E163104B1F1F4E02F163104BA
+:1003B00009F44AC022E02216310419F03B81E32FF0
+:1003C0000EC081E0D81649F092E0D91691F0DD20F8
+:1003D00009F04AC0AB81EA2F02C0BB81EB2FF0E0ED
+:1003E000E05AFF4F8081992787FD90959BBD8ABD7C
+:1003F0003BC02A81E22FF0E0EF70F070E05AFF4F2F
+:100400003B81E30FF11D8081992787FD90959BBD6E
+:100410008ABDDD2429C08D2D992787FD90956A819D
+:1004200070E0AED0AB81EA2FF0E0E05AFF4F2081C0
+:10043000332727FD3095280F391F8A818695281B81
+:1004400031093BBD2ABD10C08D2D992787FD9095A0
+:100450006A8170E095D0892B21F48EB584608EBDC1
+:10046000BCCF8EB58B7F8EBDE814F9040A051B0541
+:10047000CCF1EC81FD81EE0FFF1FEE0FFF1F2C81F1
+:100480003D81E20FF31FE65DFF4FC0803481398369
+:1004900082819381998788879181AC81BD811196F2
+:1004A000BD83AC8347015801890E911CA11CB11C6E
+:1004B000E885F985EF2B19F085B5856002C085B513
+:1004C0008A7F85BDF981FF2361F4992351F41D8250
+:1004D0001C8281E0882E912CA12CB12CEE24FF24CB
+:1004E000870140E04F5F2885398523303105D1F001
+:1004F0002430310549F12230310591F5413081F147
+:10050000423019F04423B1F52BC03981E32FF0E0DC
+:10051000EF70F070E05AFF4FEC0DF11D808183BD4C
+:1005200040E028C0EC2DF0E0E05AFF4F898186952D
+:100530002081281B842F992787FD9095698170E081
+:100540001FD0280F23BD16C0842F992787FD9095B3
+:10055000698170E015D0892B51F485B5856085BD22
+:10056000EC2DF0E0E05AFF4F808183BD03C085B5DC
+:100570008A7F85BD0894E11CF11C011D111DC4CEAC
+:1005800097FB092E07260AD077FD04D00CD006D0A1
+:1005900000201AF4709561957F4F0895F6F79095B5
+:1005A00081959F4F0895AA1BBB1B51E107C0AA1F4D
+:1005B000BB1FA617B70710F0A61BB70B881F991F04
+:1005C0005A95A9F780959095BC01CD010895F894AE
+:0205D000FFCF5B
+:1005D200ECE0D1C4B8AFA69F978D847E766F6A6433
+:1005E2005E58534F4A45423F3B3734322F2C29271E
+:1005F2002523211F1D1B1A18171614131211100F71
+:00000001FF
Index: Beep/main.c
===================================================================
--- Beep/main.c	(revision 26d7f341f56638355ccf76f8cdae59dc2a644bfb)
+++ Beep/main.c	(revision 26d7f341f56638355ccf76f8cdae59dc2a644bfb)
@@ -0,0 +1,466 @@
+/**********************************************************************
+ * Music Player for the ATMega8
+ * Uses all 3 timers for generating a 2voices, 1bit sound.
+ * Copyright 2010, Adrien Destugues <pulkomandy@pulkomandy.ath.cx>
+ * Distributed under the terms of the MIT licence
+ **********************************************************************/
+
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include <avr/wdt.h>
+#include <avr/pgmspace.h>
+#include <util/delay.h>
+
+#include <string.h>
+#include <stdbool.h>
+
+#define C2_SoundOn() TCCR2 |= (1<<CS22)|(1<<CS20) /* enable timer */
+#define C2_SoundOff() TCCR2 &= ~((1<<CS22)|(1<<CS20)) /* disable timer */
+#define C2_SetFreq(f) OCR2 = (f) 
+
+#define C1_SoundOn() TCCR1B |= (1<<CS12) /* enable timer */
+#define C1_SoundOff() TCCR1B &= ~(1<<CS12) /* disable timer */
+#define C1_SetFreq(f) OCR1A = (f)
+
+typedef enum {
+	S, // silence
+	N, // normal
+	A, // arpeggio
+	V, // vibrato
+	T, // tremolo
+} FX;
+
+// A note is made of frequency, duration, and a boolean indicating if it is 
+// silence or a real note. Things that should be changed here :
+//  * Have a note value instead of an hardcoded frequency,and have an octave
+//  * Allow for effects (arpegio, vibrato for example)
+typedef struct {
+	unsigned char n; // note
+	unsigned char d; // length
+	FX f;			 // FX
+	unsigned char p; // params
+} C2_Note;
+
+// Mapping of notes to OCR2 values for timer 2.
+static const char Note2Reg[] = {
+	0xEC,
+	0xE0,
+	0xD1,
+	0xC4,
+	0xB8,
+	0xAF,
+	0xA6,
+	0x9F,
+	0x97,
+	0x8D,
+	0x84,
+	0x7E,
+	
+	0x76,
+	0x6F,
+	0x6A,
+	0x64,
+	0x5E,
+	0x58,
+	0x53,
+	0x4F,
+	0x4A,
+	0x45,
+	0x42,
+	0x3F,
+
+	0x3B, // C
+	0x37, // C#
+	0x34, // D
+	0x32, // D#
+	0x2F, // E
+	0x2C, // F
+	0x29, // F#
+	0x27, // G
+	0x25, // G#
+	0x23, // A
+	0x21, // A#
+	0x1F, // B
+
+	0x1D, // C
+	0x1B, // C#
+	0x1A, // D
+	0x18, // D#
+	0x17, // E
+	0x16, // F
+	0x14, // F#
+	0x13, // G
+	0x12, // G#
+	0x11, // A
+	0x10, // A#
+	0xF  // B
+	//0xE,  // C
+	//0xD   // C#
+};
+
+#define C(n) 12*n
+#define Cs(n) C(n)+1
+#define D(n) C(n)+2
+#define Ds(n) C(n)+3
+#define E(n) C(n)+4
+#define F(n) C(n)+5
+#define Fs(n) C(n)+6
+#define G(n) C(n)+7
+#define Gs(n) C(n)+8
+#define A(n) C(n)+9
+#define As(n) C(n)+10
+#define B(n) C(n)+11
+
+// Song data. A list of notes. Looped.
+/*
+static const C2_Note song[] = {
+	{ G(2),  10, N, 0x00 },
+	{ 0,      1, S, 0x00 },
+	{ G(2),  10, N, 0x00 },
+	{ 0,      1, S, 0x00 },
+	{ G(2),  10, N, 0x00 },
+	{ 0,      1, S, 0x00 },
+	{ Ds(2),  7, N, 0x00 },
+	{ As(2),  4, N, 0x00 },
+	{ G(2),  10, N, 0x00 },
+	{ 0,      1, S, 0x00 },
+	{ Ds(2),  7, N, 0x00 },
+	{ As(2),  4, N, 0x00 },
+	{ G(2),  10, N, 0x00 },
+	{ 0,      7, S, 0x00 },
+
+	{ D(3),  10, N, 0x00 },
+	{ 0,      1, S, 0x00 },
+	{ D(3),  10, N, 0x00 },
+	{ 0,      1, S, 0x00 },
+	{ D(3),  10, N, 0x00 },
+	{ 0,      1, S, 0x00 },
+	{ Ds(3),  7, N, 0x00 },
+	{ As(2),  4, N, 0x00 },
+	{ Fs(2), 10, N, 0x00 },
+	{ 0,      1, S, 0x00 },
+	{ Ds(2),  7, N, 0x00 },
+	{ As(2),  4, N, 0x00 },
+	{ G(2),  10, N, 0x00 },
+	{ 0,      7, S, 0x00 },
+
+	{ G(3),  10, N, 0x00 },
+	{ 0,      1, S, 0x00 },
+	{ G(3),  10, N, 0x00 },
+	{ 0,      1, S, 0x00 },
+	{ G(3),  10, N, 0x00 },
+	{ 0,      1, S, 0x00 },
+	{ G(3),   6, N, 0x00 },
+	{ 0,      1, S, 0x00 },
+	{ Fs(3),  2, N, 0x00 },
+	{ F(3),   2, N, 0x00 },
+	{ E(3),   3, N, 0x00 },
+	{ Ds(3),  7, N, 0x00 },
+	{ 0,      1, S, 0x00 },
+	{ E(2),   4, N, 0x00 },
+	{ Gs(2), 10, N, 0x00 },
+	{ 0,      4, S, 0x00 },
+
+	{ Cs(3),  4, N, 0x00 },
+	{ C(3),   4, N, 0x00 },
+	{ B(2),   4, N, 0x00 },
+	{ As(2),  4, N, 0x00 },
+	{ A(2),   4, N, 0x00 },
+
+
+	{ 0,     40, S, 0x00 },
+	{0,0,0} // Song end marker - zero-length note
+};
+*/
+
+static const C2_Note song[] PROGMEM = {
+	{ E(3),   8, N, 0x00 },
+	{ B(2),   4, N, 0x00 },
+	{ C(3),   4, N, 0x00 },
+	{ D(3),   4, N, 0x00 },
+	{ 0   ,   4, S, 0x00 },
+	{ C(3),   4, N, 0x00 },
+	{ B(2),   4, N, 0x00 },
+	{ A(2),   4, N, 0x00 },
+	{ 0   ,   4, S, 0x00 },
+	{ A(2),   4, N, 0x00 },
+	{ C(3),   4, N, 0x00 },
+	{ E(3),   4, N, 0x00 },
+	{ 0   ,   4, S, 0x00 },
+	{ D(3),   4, N, 0x00 },
+	{ C(3),   4, N, 0x00 },
+	{ B(2),   4, N, 0x00 },
+	{ 0   ,   8, S, 0x00 },
+	{ C(3),   4, N, 0x00 },
+	{ D(3),   8, N, 0x00 },
+	{ E(3),   8, N, 0x00 },
+	{ C(3),   8, N, 0x00 },
+	{ A(2),   7, N, 0x00 },
+	{ 0   ,   1, S, 0x00 },
+	{ A(2),   8, N, 0x00 },
+	{ 0   ,   8, S, 0x00 },
+
+	{ D(3),  12, N, 0x00 },
+	{ F(3),   4, N, 0x00 },
+	{ A(3),   8, N, 0x00 },
+	{ G(3),   4, N, 0x00 },
+	{ F(3),   4, N, 0x00 },
+	{ E(3),   8, N, 0x00 },
+	{ 0   ,   4, S, 0x00 },
+	{ C(3),   4, N, 0x00 },
+	{ E(3),   8, N, 0x00 },
+	{ D(3),   4, N, 0x00 },
+	{ C(3),   4, N, 0x00 },
+	{ B(2),   4, N, 0x00 },
+	{ 0   ,   8, S, 0x00 },
+	{ C(3),   4, N, 0x00 },
+	{ D(3),   8, N, 0x00 },
+	{ E(3),   8, N, 0x00 },
+	{ C(3),   8, N, 0x00 },
+	{ A(2),   7, N, 0x00 },
+	{ 0   ,   1, S, 0x00 },
+	{ A(2),   8, N, 0x00 },
+	{ 0   ,   8, S, 0x00 },
+
+/*
+	{ E(3),   8, N, 0x00 },
+	{ B(2),   4, N, 0x00 },
+	{ C(3),   4, N, 0x00 },
+	{ D(3),   4, N, 0x00 },
+	{ 0   ,   4, S, 0x00 },
+	{ C(3),   4, N, 0x00 },
+	{ B(2),   4, N, 0x00 },
+	{ A(2),   4, N, 0x00 },
+	{ 0   ,   4, S, 0x00 },
+	{ A(2),   4, N, 0x00 },
+	{ C(3),   4, N, 0x00 },
+	{ E(3),   4, N, 0x00 },
+	{ 0   ,   4, S, 0x00 },
+	{ D(3),   4, N, 0x00 },
+	{ C(3),   4, N, 0x00 },
+	{ B(2),   4, N, 0x00 },
+	{ 0   ,   8, S, 0x00 },
+	{ C(3),   4, N, 0x00 },
+	{ D(3),   8, N, 0x00 },
+	{ E(3),   8, N, 0x00 },
+	{ C(3),   8, N, 0x00 },
+	{ A(2),   7, N, 0x00 },
+	{ 0   ,   1, S, 0x00 },
+	{ A(2),   8, N, 0x00 },
+	{ 0   ,   8, S, 0x00 },
+
+	{ D(3),  12, N, 0x00 },
+	{ F(3),   4, N, 0x00 },
+	{ A(3),   8, N, 0x00 },
+	{ G(3),   4, N, 0x00 },
+	{ F(3),   4, N, 0x00 },
+	{ E(3),   8, N, 0x00 },
+	{ 0   ,   4, S, 0x00 },
+	{ C(3),   4, N, 0x00 },
+	{ E(3),   8, N, 0x00 },
+	{ D(3),   4, N, 0x00 },
+	{ C(3),   4, N, 0x00 },
+	{ B(2),   4, N, 0x00 },
+	{ 0   ,   8, S, 0x00 },
+	{ C(3),   4, N, 0x00 },
+	{ D(3),   8, N, 0x00 },
+	{ E(3),   8, N, 0x00 },
+	{ C(3),   8, N, 0x00 },
+	{ A(2),   7, N, 0x00 },
+	{ 0   ,   1, S, 0x00 },
+	{ A(2),   8, N, 0x00 },
+	{ 0   ,   8, S, 0x00 },
+*/
+	{ E(3),  16, N, 0x00 },
+	{ C(3),  16, N, 0x00 },
+	{ D(3),  16, N, 0x00 },
+	{ B(2),  16, N, 0x00 },
+	{ C(3),  16, N, 0x00 },
+	{ A(2),  16, N, 0x00 },
+	{ G(2),  16, N, 0x00 },
+	{ Gs(2), 16, N, 0x00 },
+
+	{ 0   ,   8, S, 0x00 },
+
+	{ E(3),  16, N, 0x00 },
+	{ C(3),  16, N, 0x00 },
+	{ D(3),  16, N, 0x00 },
+	{ B(2),  16, N, 0x00 },
+
+	{ C(3),   8, N, 0x00 },
+	{ D(3),   8, N, 0x00 },
+
+	{0,0,S,0} // Song end marker - zero-length note
+};
+
+static const C2_Note song2[] PROGMEM = {
+	{ C(2), 4, N, 0x00 },
+	{ C(3), 4, N, 0x00 },
+	{ C(2), 4, N, 0x00 },
+	{ C(3), 4, N, 0x00 },
+	{ C(2), 4, N, 0x00 },
+	{ C(3), 4, N, 0x00 },
+	{ C(2), 4, N, 0x00 },
+	{ C(3), 4, N, 0x00 },
+
+	{ G(2), 4, N, 0x00 },
+	{ G(3), 4, N, 0x00 },
+	{ G(2), 4, N, 0x00 },
+	{ G(3), 4, N, 0x00 },
+	{ G(2), 4, N, 0x00 },
+	{ G(3), 4, N, 0x00 },
+	{ G(2), 4, N, 0x00 },
+	{ G(3), 4, N, 0x00 },
+
+	{ E(2), 4, N, 0x00 },
+	{ E(3), 4, N, 0x00 },
+	{ E(2), 4, N, 0x00 },
+	{ E(3), 4, N, 0x00 },
+	{ B(1), 4, N, 0x00 },
+	{ B(2), 4, N, 0x00 },
+	{ B(1), 4, N, 0x00 },
+	{ B(2), 4, N, 0x00 },
+
+	{ C(2), 4, N, 0x00 },
+	{ C(3), 4, N, 0x00 },
+	{ C(2), 4, N, 0x00 },
+	{ C(3), 4, N, 0x00 },
+	{ C(2), 16, N, 0x00 },
+
+	{0,0,S,0} // Song end marker - zero-length note
+};
+
+// This allows us to know where we are in the song.
+volatile int tick;
+
+// Timer 0 interrupt handler
+ISR(TIMER0_OVF_vect)
+{
+	tick++;
+}
+
+void main() {
+	// WATCHDOG
+	wdt_enable(WDTO_2S);
+
+	// TIMER 0 : timebase, 1 tick every 1ms
+	TCCR0 =(1<<CS02) | (1<<CS00); // prescaler /1024
+	TIMSK = 1 << TOIE0; // enable timer interrupt
+	tick = 0;
+	
+	// TIMER 1 : Freq generator
+	TCCR1A = (1<<COM1A0);
+	TCCR1B = (1<<WGM12);
+
+	OCR1A = 0x5E;
+
+	// TIMER 2 : Frequency generator (on OC2)
+	// CTC mode allows us to set the frequency through OCR2 register
+	// Prescaler is set to 1024 in C2_SoundOn.
+    TCCR2 = (1<<WGM21) // CTC
+		|(1<<COM20); // toggle output on match
+	ASSR = 0; // Disable async mode
+
+	// Port B as output so we can use the timers
+	DDRB = 255;
+
+	// Enable interrupts
+	sei();
+
+
+	// TEST
+	//OCR2 = 0xFF;
+	//C2_SoundOn();
+
+	int step = 0;
+	int step2 = 0;
+	long nexttime = 0;
+	long nexttime2 = 0;
+	long time = 0;
+	char subtick = 0;
+	char subtick2 = 0;
+	C2_Note current = song[0];
+	C2_Note current2 = song2[0];
+
+	PORTB = 0xFF;
+
+	// Main loop
+	while(1) {
+		wdt_reset();
+
+		// PLAYER CODE
+		if (tick) {
+			tick--;
+			
+
+			// CHANNEL 1 ---------------------------------
+			if (nexttime <= time) {
+		   		current = song2[step];
+				step++;
+				subtick = 0;
+				// Go to next step
+				nexttime = time + current.d;
+				if(current.f != 0) C1_SoundOn();
+				else C1_SoundOff();
+
+				// Test if song is finished, if so loop over
+				if (current.p == S && current.d == 0) {
+					step = 0;
+					time = 0;
+					nexttime = 1;
+				}
+			}
+
+			subtick++;
+			switch (current.f) {
+				default: case N: C1_SetFreq(Note2Reg[current.n]); break;
+				case A: 
+					switch(subtick) {
+						case 0: C1_SetFreq(Note2Reg[current.n + ((current.p&0xF0)>>8)]); break;
+						case 1: C1_SetFreq(Note2Reg[current.n]); break;
+						case 2: C1_SetFreq(Note2Reg[current.n + (current.p&0xF)]); subtick = 0; break;
+					}
+					break;
+				case V: C1_SetFreq(Note2Reg[current.n]-current.p/2+subtick%current.p); break;
+				case T: if(subtick%current.p == 0) { C1_SoundOn(); C1_SetFreq(Note2Reg[current.n]); } else C1_SoundOff(); break;
+			}
+
+
+			// CHANNEL 2 -------------------------------
+			if (nexttime2 <= time) {
+		   		current2 = song[step2];
+				step2++;
+				subtick2 = 0;
+				// Go to next step
+				nexttime2 = time + current2.d;
+				if(current2.f != 0) C2_SoundOn();
+				else C2_SoundOff();
+
+				// Test if song is finished, if so loop over
+				if (current2.p == S && current2.d == 0) {
+					step2 = 0;
+					time = 0;
+					nexttime2 = 1;
+				}
+			}
+
+			subtick2++;
+			switch (current2.f) {
+				default: case N: C2_SetFreq(Note2Reg[current2.n]); break;
+				case A: 
+					switch(subtick2) {
+						case 0: C2_SetFreq(Note2Reg[current2.n + ((current2.p&0xF0)>>8)]); break;
+						case 1: C2_SetFreq(Note2Reg[current2.n]); break;
+						case 2: C2_SetFreq(Note2Reg[current2.n + (current2.p&0xF)]); subtick2 = 0; break;
+					}
+					break;
+				case V: C2_SetFreq(Note2Reg[current2.n]-current2.p/2+subtick2%current2.p); break;
+				case T: if(subtick2%current2.p == 0) { C2_SoundOn(); C2_SetFreq(Note2Reg[current2.n]); } else C2_SoundOff(); break;
+			}
+
+
+			time++;
+		}
+	}
+}
+
