Index: code/C/meatracker/Makefile
===================================================================
--- code/C/meatracker/Makefile	(revision 2495b14d5a6ceedddd5d866f80f7a6aa6d1a4146)
+++ code/C/meatracker/Makefile	(revision 90b6d4b9f9cfd11d9ab43c427ea09fd3e4af4870)
@@ -3,9 +3,9 @@
 	cp obj/tracker.K5 ../../../../mo5/dcmo5/software/tracker.K7
 
-obj/tracker.bin:: obj/main.o obj/display.o obj/text.o obj/font_hs2.o
+obj/tracker.bin:: obj/main.o obj/display.o obj/text.o obj/font_hs2.o obj/input.o
 
 ###############################################################################
 CC=m6809-thomson-none-gcc
-CFLAGS=-O3 -save-temps=obj -Wall
+CFLAGS=-O3 -save-temps=obj -Wall -std=gnu99
 
 obj/%.K5: obj/%.bin
Index: code/C/meatracker/display.c
===================================================================
--- code/C/meatracker/display.c	(revision 2495b14d5a6ceedddd5d866f80f7a6aa6d1a4146)
+++ code/C/meatracker/display.c	(revision 90b6d4b9f9cfd11d9ab43c427ea09fd3e4af4870)
@@ -1,7 +1,11 @@
+#include "display.h"
+
 #include <text.h>
+
+char music[8][16];
 
 static const char* notes = "C C#D D#E F F#G G#A A#B --";
 
-static const char FM1[] = {
+const char FM1[] = {
 2,'3',  4,'3', 5,'3',  6,'3', 7,'3',  9,'3', 10,'3', 11,'3',
 0,'4',  2,'4', 3,'4',  4,'4', 5,'4',  6,'4',  7,'4',  8,'4',
@@ -11,5 +15,5 @@
 };
 
-static const char FM2[] = {
+const char FM2[] = {
 9,'4', 10,'4', 11,'4', 0,'5', 1,'5',  2,'5',  3,'5',  4,'5',
 5,'5',  6,'5',  7,'5', 8,'5', 9,'5', 10,'5', 11,'5',  0,'6',
@@ -19,5 +23,5 @@
 };
 
-static const char FM3[] = {
+const char FM3[] = {
 2,'6', 4,'6', 7,'6', 9,'6', 0,'7', 2,'7', 5,'7', 8,'7'
 };
@@ -25,10 +29,12 @@
 static const char FM4[] = { 9,'7' };
 
-void printnote(char channel, char pos, char note)
+void printnote(unsigned char channel, unsigned char pos)
 {
-	if (channel > 3) return;
+	if (channel > 6) return;
 
-	char n, o;
-	pos *= 8;
+	uint8_t note = music[channel][pos];
+	char fbw = '1' + music[channel+1][pos];
+
+	uint8_t n = 12, o = '?';
 	if (note >= 0)
 	{
@@ -39,23 +45,29 @@
 			n = FM1[note]; o = FM1[note+1];
 			break;
-		case 1:
+		case 2:
 			n = FM2[note]; o = FM2[note+1];
 			break;
-		case 2:
+		case 4:
 			n = FM3[note]; o = FM3[note+1];
 			break;
-		case 3:
+		case 6:
 			n = FM4[note]; o = FM4[note+1];
 			break;
 	}
-	} else {
-		n = 12;
 	}
 
-	channel *= 5;
+
+	pos *= 8;
+
+	if(channel == 2) channel = 5;
+	else if(channel == 4) channel = 10;
+	else if(channel == 6) channel = 15;
+
 	n *= 2;
+
 	drawchar(notes[n],     channel++, pos);
 	drawchar(notes[n + 1], channel++, pos);
-	drawchar(o,            channel,   pos);
+	drawchar(o,            channel++, pos);
+	drawchar(fbw,          channel,   pos);
 }
 
@@ -64,8 +76,37 @@
 	int x,y;
 
-	for(x = 0; x < 4; x++)
+	for(x = 0; x < 8; x+=2)
 	for(y = 0; y < 16; y++)
 	{
-		printnote(x, y, 0);
+		printnote(x, y);
 	}
+
+	// TODO HEADER
+	// FM1  FM2  FM3  FM4  GEN
+	// nnnW nnnW nnnW nnnW sldCRVD
+	// ---  ---  ---  ---  nnnCR                   
+
+	cursor(cursorx, cursory);
 }
+
+void cursor(uint8_t x, uint8_t y)
+{
+	uint8_t* destp = (uint8_t*)(x*2) + y * 8 * 40;
+
+	if(x>1) ++destp;
+	if(x>3) ++destp;
+	if(x>5) ++destp;
+	if(x>7) ++destp;
+
+	int val = 0xFFFF;
+	if(x == 1 || x == 3 || x == 5 || x == 7) val = 0xFF;
+	uint16_t* dest = (uint16_t*)destp;
+	*dest ^= val; dest +=20;
+	*dest ^= val; dest +=20;
+	*dest ^= val; dest +=20;
+	*dest ^= val; dest +=20;
+	*dest ^= val; dest +=20;
+	*dest ^= val; dest +=20;
+	*dest ^= val; dest +=20;
+	*dest ^= val; dest +=20;
+}
Index: code/C/meatracker/display.h
===================================================================
--- code/C/meatracker/display.h	(revision 2495b14d5a6ceedddd5d866f80f7a6aa6d1a4146)
+++ code/C/meatracker/display.h	(revision 90b6d4b9f9cfd11d9ab43c427ea09fd3e4af4870)
@@ -1,1 +1,6 @@
+#include "stdint.h"
+
 void refreshchannels();
+void cursor(uint8_t x, uint8_t y);
+
+extern unsigned char cursorx, cursory;
Index: code/C/meatracker/input.c
===================================================================
--- code/C/meatracker/input.c	(revision 90b6d4b9f9cfd11d9ab43c427ea09fd3e4af4870)
+++ code/C/meatracker/input.c	(revision 90b6d4b9f9cfd11d9ab43c427ea09fd3e4af4870)
@@ -0,0 +1,127 @@
+#include "display.h"
+
+unsigned char cursorx = 0, cursory = 7;
+
+extern const char FM1[], FM2[], FM3[];
+extern unsigned char music[8][16];
+void printnote(unsigned char x, unsigned char y);
+
+// maps keycodes to notes
+static const unsigned char notemap[] =
+{
+	[0x60] = 0,  // W
+	[0x50] = 2,  // X
+	[0x64] = 4,  // C
+	[0x54] = 6,  // V
+	[0x44] = 8,  // B
+	[0x00] = 10, // N
+	[0x10] = 12, // ,
+	[0x20] = 14, // .
+	[0x30] = 16, // @
+   	[0x22] = 18, // back
+   	[0x56] = 20, // Q
+   	[0x46] = 22, // S
+   	[0x36] = 24, // D
+   	[0x26] = 26, // F
+   	[0x16] = 28, // G
+   	[0x06] = 30, // H
+	[0x04] = 32, // J
+	[0x14] = 34, // K
+	[0X24] = 36, // L
+	[0x34] = 38, // M
+	[0x5A] = 40, // A
+	[0x4A] = 42, // Z
+	[0x3A] = 44, // E
+	[0x2A] = 46, // R
+	[0x1A] = 48, // T
+	[0x0A] = 50, // Y
+	[0x08] = 52, // U
+	[0x18] = 54, // I
+	[0x28] = 56, // O
+	[0x38] = 58, // P
+	[0x48] = 60, // /
+	[0x58] = 61, // *
+	// JKLM AZERTY UIOP/*
+};
+
+void input()
+{
+	// scan keyboard
+	volatile unsigned char* volatile PIA_B = (volatile unsigned char* volatile)0xA7C1;
+
+	for(unsigned char k = 0; k < 127; k+= 2)
+	{
+		*PIA_B = k;
+
+		if(!(*PIA_B & 0x80))
+		{
+			// We have a keypress !
+			switch(k)
+			{
+				case 0x32: //RIGHT
+					if(cursorx == 11) break;
+					cursor(cursorx,cursory);
+					cursorx ++;
+					cursor(cursorx,cursory);
+					break;
+				case 0x42: //DOWN
+					if(cursory == 15) break;
+					cursor(cursorx,cursory);
+					cursory ++;
+					cursor(cursorx,cursory);
+					break;
+				case 0x52: //LEFT
+					if(cursorx == 0) break;
+					cursor(cursorx,cursory);
+					cursorx --;
+					cursor(cursorx,cursory);
+					break;
+				case 0x62: //UP
+					if (cursory == 0) break;
+					cursor(cursorx,cursory);
+					cursory --;
+					cursor(cursorx,cursory);
+					break;
+
+				// TODO handle octave / width / more ?
+				default:
+				{
+				// direclty assigning from array to array generates buggy code
+					uint8_t note = notemap[k];
+					switch(cursorx)
+					{
+						case 0:
+						case 2:
+						case 4:
+						case 6:
+							music[cursorx][cursory] = note;
+							printnote(cursorx, cursory);
+							cursor(cursorx, cursory);
+							break;
+
+						case 1:
+						case 3:
+						case 5:
+						case 7:
+						{
+							uint8_t channel = cursorx - 1;
+							if(k == 0x5E)
+								music[channel + 1][cursory] = 0;
+							else if (k == 0x4E)
+								music[channel + 1][cursory] = 1;
+							else if (k == 0x3E)
+								music[channel + 1][cursory] = 2;
+							else if (k == 0x2E)
+								music[channel + 1][cursory] = 3;
+							printnote(cursorx - 1, cursory);
+							cursor(cursorx, cursory);
+						}
+					}
+					break;
+				}
+			}
+		}
+	}
+	
+	// TODO extra widgets besides the tracker ? diskop, etc ?
+}
Index: code/C/meatracker/input.h
===================================================================
--- code/C/meatracker/input.h	(revision 90b6d4b9f9cfd11d9ab43c427ea09fd3e4af4870)
+++ code/C/meatracker/input.h	(revision 90b6d4b9f9cfd11d9ab43c427ea09fd3e4af4870)
@@ -0,0 +1,1 @@
+void input();
Index: code/C/meatracker/main.c
===================================================================
--- code/C/meatracker/main.c	(revision 2495b14d5a6ceedddd5d866f80f7a6aa6d1a4146)
+++ code/C/meatracker/main.c	(revision 90b6d4b9f9cfd11d9ab43c427ea09fd3e4af4870)
@@ -6,8 +6,59 @@
 
 #include "display.h"
+#include "input.h"
+
+volatile unsigned char* MEA_DATA = (unsigned char*)0xA7CE;
+extern unsigned char music[8][16];
+
+uint8_t isplaying = 1;
 
 int main(void)
 {
+	asm(" ORCC #$50"); // Disable interrupts (cursor blink)
 	refreshchannels();
+
+
+	for(int frame = 0;;frame++)
+	{
+		if((frame & 0x3) == 0)
+			input();
+		
+		if(isplaying)
+		{
+			/*
+			*MEA_DATA = music[0][frame & 0xF];
+			*MEA_DATA = music[1][frame & 0xF];
+			*MEA_DATA = music[2][frame & 0xF];
+			*MEA_DATA = music[3][frame & 0xF];
+			*/
+
+			*(MEA_DATA + 1) = 0x12;
+			*MEA_DATA = 110;
+
+			// BW
+			*MEA_DATA = (music[1][frame & 0xF] << 6) |
+						(music[3][frame & 0xF] << 4) |
+						(music[5][frame & 0xF] << 2) |
+						(music[7][frame & 0xF]);
+
+			// FREQ
+			*MEA_DATA = (music[2][frame & 0xF] << 5) |
+						(music[4][frame & 0xF]);
+
+			// FREQ / AMPL
+			*MEA_DATA = (music[0][frame & 0xF] << 3) | 0xF; // TODO AMPL
+
+			// AMPL / DUR / PERIODCHANGE
+			*MEA_DATA = 0xD1; // TODO AMPL / DUR / PERIODCHANGE
+		}
+
+		asm("\n"
+"z	TST	0xA7E7	\n"
+"	BMI z		\n"
+"bb	TST	0xA7E7	\n"
+"	BPL bb		\n"
+		);
+	}
+
 	return 0;
 }
