Work on MEATrakcer continues with some input and cursor handling.
git-svn-id: svn://localhost/thomson@44 85ae3b6b-dc8f-4344-a89d-598714f2e4e5
diff --git a/code/C/meatracker/Makefile b/code/C/meatracker/Makefile
index be22db7..bf56b1f 100644
--- a/code/C/meatracker/Makefile
+++ b/code/C/meatracker/Makefile
@@ -2,11 +2,11 @@
all: obj/tracker.K5
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
f2k5 $<
diff --git a/code/C/meatracker/display.c b/code/C/meatracker/display.c
index de207b6..a81fc3c 100644
--- a/code/C/meatracker/display.c
+++ b/code/C/meatracker/display.c
@@ -1,8 +1,12 @@
+#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',
// >> FM2
@@ -10,7 +14,7 @@
5,'5', 6,'5', 7,'5', 8,'5', 9,'5', 10,'5', 11,'5', 0,'6'
};
-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',
// << FM1
@@ -18,18 +22,20 @@
10,'6', 0,'7', 1,'7', 2,'7', 4,'7', 5,'7', 7,'7', 8,'7'
};
-static const char FM3[] = {
+const char FM3[] = {
2,'6', 4,'6', 7,'6', 9,'6', 0,'7', 2,'7', 5,'7', 8,'7'
};
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)
{
note *= 2;
@@ -38,34 +44,69 @@
case 0:
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);
}
void refreshchannels()
{
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;
}
diff --git a/code/C/meatracker/display.h b/code/C/meatracker/display.h
index 8730ddf..152eabc 100644
--- a/code/C/meatracker/display.h
+++ b/code/C/meatracker/display.h
@@ -1 +1,6 @@
+#include "stdint.h"
+
void refreshchannels();
+void cursor(uint8_t x, uint8_t y);
+
+extern unsigned char cursorx, cursory;
diff --git a/code/C/meatracker/input.c b/code/C/meatracker/input.c
new file mode 100644
index 0000000..328417f
--- /dev/null
+++ b/code/C/meatracker/input.c
@@ -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 ?
+}
diff --git a/code/C/meatracker/input.h b/code/C/meatracker/input.h
new file mode 100644
index 0000000..a1f997e
--- /dev/null
+++ b/code/C/meatracker/input.h
@@ -0,0 +1 @@
+void input();
diff --git a/code/C/meatracker/main.c b/code/C/meatracker/main.c
index a639d45..8ad5324 100644
--- a/code/C/meatracker/main.c
+++ b/code/C/meatracker/main.c
@@ -5,9 +5,60 @@
*/
#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;
}