? changelog.meow
? errlist.txt
Index: keyboard.c
===================================================================
RCS file: /cvsroot/x0xb0x/firmware/keyboard.c,v
retrieving revision 1.4
diff -u -r1.4 keyboard.c
--- keyboard.c	2 Aug 2005 15:28:27 -0000	1.4
+++ keyboard.c	13 Jan 2006 13:19:04 -0000
@@ -64,8 +64,9 @@
 
 void do_keyboard_mode(void) {
   signed int shift = 0;
-  uint8_t accent=0, slide=0;
+  uint8_t accent=FALSE, slide=FALSE;
   uint8_t i, last_bank;
+  uint8_t note;
   
   // turn tempo off!
   turn_on_tempo();
@@ -104,18 +105,24 @@
 
     // show the octave
     display_octave_shift(shift);
+    if (accent) set_led(LED_ACCENT);
+    if (slide)  set_led(LED_SLIDE);
 
     for (i=0; i<13; i++) {
       // check if any notes were just pressed
       if (just_pressed(notekey_tab[i])) {
-	note_on((C2+i) + shift*OCTAVE, slide, accent);
-	midi_send_note_on( ((C2+i) + shift*OCTAVE) | (accent << 6));
+	note = (C2+i) + shift*OCTAVE;
+	note_on(note, slide, accent);
+	midi_send_note_on(note | (accent << 6));
+	set_note_led(note);
 	slide = TRUE;
       }
       
       // check if any notes were released
       if (just_released(notekey_tab[i])) {
-	midi_send_note_off( ((C2+i) + shift*OCTAVE) | (accent << 6));
+	note = (C2+i) + shift*OCTAVE;
+	midi_send_note_off(note | (accent << 6));
+	clear_note_leds();
       }
     }
 
@@ -140,6 +147,7 @@
     // turn off the note.
     if ((NOTE_PIN & 0x3F) && no_keys_pressed()) {
       note_off(0);
+      clear_note_leds();  // ?
       slide = FALSE;
     }
   }
Index: led.c
===================================================================
RCS file: /cvsroot/x0xb0x/firmware/led.c,v
retrieving revision 1.7
diff -u -r1.7 led.c
--- led.c	2 Aug 2005 15:28:27 -0000	1.7
+++ led.c	13 Jan 2006 13:19:05 -0000
@@ -39,10 +39,19 @@
 #include "led.h"
 #include "synth.h"
 
-uint8_t leds[5] = {0,0,0,0,0};
-uint8_t blinkleds[5] = {0,0,0,0,0};
+#define NUM_BANKS 16
+#define NUM_LEDS_KEY     24
+#define NUM_LEDS_NOTEKEY 13
+#define NUM_LEDS_NUMKEY   8
+
+// 40-bit wide bitfields, one bit per LED. The main() loop overlays
+// blinkleds overtop leds (and removes them from LEDs also), leds is
+// actually used to control the state at any given time
+#define LED_BYTES 5
+uint8_t leds[LED_BYTES] = {0,0,0,0,0};
+uint8_t blinkleds[LED_BYTES] = {0,0,0,0,0};
 
-const static uint8_t bank_led_tab[16] = {
+const static uint8_t bank_led_tab[NUM_BANKS] = {
   LED_BANK1,
   LED_BANK2,
   LED_BANK3,
@@ -61,7 +70,7 @@
   LED_BANK16
 };
 
-const static uint8_t key_led_tab[24] = {
+const static uint8_t key_led_tab[NUM_LEDS_KEY] = {
   LED_CHAIN,
   LED_RS,
   LED_TEMPO,
@@ -91,7 +100,7 @@
 };
 
 // table for converting notes (C = 0, C2 = 12) into leds
-const static uint8_t notekey_led_tab[13] = {
+const static uint8_t notekey_led_tab[NUM_LEDS_NOTEKEY] = {
   LED_C,
   LED_CS,
   LED_D,
@@ -108,7 +117,7 @@
 };
 
 // table for converting numbered keys into leds
-const static uint8_t numkey_led_tab[8] = {
+const static uint8_t numkey_led_tab[NUM_LEDS_NUMKEY] = {
   LED_C,
   LED_D,
   LED_E,
@@ -162,13 +171,20 @@
 
 void clear_bank_leds(void) {
   uint8_t  i;
-  for (i=0; i<16; i++) {
+  for (i=0; i<NUM_BANKS; i++) {
     clear_led(bank_led_tab[i]);
   }
 }
 
+void clear_bank_leds_blink(void) {
+  uint8_t  i;
+  for (i=0; i<NUM_BANKS; i++) {
+    clear_led_blink(bank_led_tab[i]);
+  }
+}
+
 void set_bank_led(uint8_t num) {
-  if (num >= 16)
+  if (num >= NUM_BANKS)
     return;
   set_led(bank_led_tab[num]);
 }
@@ -176,7 +192,7 @@
 /*
 void set_single_bank_led(uint8_t num) {
   uint8_t i;
-  for (i=0; i<16; i++)
+  for (i=0; i<NUM_BANKS; i++)
     if (num == i)
       set_led(bank_led_tab[num]);
     else
@@ -185,45 +201,45 @@
 */
 
 void set_bank_led_blink(uint8_t num) {
-  if (num >= 16)
+  if (num >= NUM_BANKS)
     return;
   set_led_blink(bank_led_tab[num]);
 }
 
 uint8_t is_bank_led_set(uint8_t num) {
- if (num >= 16)
-    return 0;
+ if (num >= NUM_BANKS)
+    return FALSE;
   return is_led_set(bank_led_tab[num]);
 }
 
 uint8_t is_bank_led_blink(uint8_t num) { 
-  if (num >= 16)
-    return 0;
+  if (num >= NUM_BANKS)
+    return FALSE;
   return is_led_blink(bank_led_tab[num]);
 }
 
 // key leds (all but tempo/bank)
 void set_key_led(uint8_t num) {
-  if (num >= 24)
+  if (num >= NUM_LEDS_KEY)
     return;
   set_led(key_led_tab[num]);
 }
 
 void set_key_led_blink(uint8_t num) {
-  if (num >= 24)
+  if (num >= NUM_LEDS_KEY)
     return;
   set_led_blink(key_led_tab[num]);
 }
 
 void clear_key_led(uint8_t num) {
-  if (num >= 24)
+  if (num >= NUM_LEDS_KEY)
     return;
   clear_led(key_led_tab[num]);
 }
 
 void clear_key_leds(void) {
   uint8_t i;
-  for (i=0; i<24; i++) {
+  for (i=0; i<NUM_LEDS_KEY; i++) {
     clear_led(key_led_tab[i]);
   }
 }
@@ -231,13 +247,13 @@
 // numbered keys (bottom row 1 thru 8)
 
 void set_numkey_led(uint8_t num) {
-  if ((num >= 1) && (num <= 8))
+  if ((num >= 1) && (num <= NUM_LEDS_NUMKEY))
     set_led(numkey_led_tab[num-1]);   // num is 1 thru 8
 }
 
 void set_single_numkey_led(uint8_t num) {
   uint8_t i;
-  for (i=1; i <= 8; i++)
+  for (i=1; i <= NUM_LEDS_NUMKEY; i++)
     if (i == num) 
       set_led(numkey_led_tab[i-1]);
     else
@@ -245,31 +261,36 @@
 }
 
 void clear_numkey_led(uint8_t num) {
-  if ((num >= 1) && (num <= 8))
+  if ((num >= 1) && (num <= NUM_LEDS_NUMKEY))
     clear_led(numkey_led_tab[num-1]);   // num is 1 thru 8
 }
 
+void clear_numkey_led_blink(uint8_t num) {
+  if ((num >= 1) && (num <= NUM_LEDS_NUMKEY))
+    clear_led_blink(numkey_led_tab[num-1]);   // num is 1 thru 8
+}
+
 void set_numkey_led_blink(uint8_t num) {
-  if ((num >= 1) && (num <= 8))
+  if ((num >= 1) && (num <= NUM_LEDS_NUMKEY))
     set_led_blink(numkey_led_tab[num-1]);
 }
 
 uint8_t is_numkey_led_blink(uint8_t num) {
-  if ((num >= 1) && (num <= 8))
+  if ((num >= 1) && (num <= NUM_LEDS_NUMKEY))
     return is_led_blink(numkey_led_tab[num-1]);
-  return 0;
+  return FALSE;
 }
 
 
 uint8_t is_numkey_led_set(uint8_t num) {
-  if ((num >= 1) && (num <= 8))
+  if ((num >= 1) && (num <= NUM_LEDS_NUMKEY))
     return is_led_set(numkey_led_tab[num-1]);
-  return 0;
+  return FALSE;
 }
 
 void clear_numkey_leds(void) {
   uint8_t i;
-  for (i = 0; i < 8; i++) {
+  for (i = 0; i < NUM_LEDS_NUMKEY; i++) {
     clear_led(numkey_led_tab[i]);
   }
 }
@@ -292,7 +313,7 @@
 
 void clear_notekey_leds(void) {
   uint8_t i;
-  for (i = 0; i < 13; i++) {
+  for (i = 0; i < NUM_LEDS_NOTEKEY; i++) {
     clear_led(notekey_led_tab[i]);
   }
 }
@@ -356,7 +377,7 @@
 
   cli();
   cbi(LED_LATCH_PORT, LED_LATCH_PIN);
-  for (i=0; i<5; i++) {
+  for (i=0; i<LED_BYTES; i++) {
     SPDR = leds[i];
     while (!(SPSR & (1<<SPIF)));
   }
@@ -367,21 +388,21 @@
 void blink_leds_on(void) {
   uint8_t i;
 
-  for (i=0; i<5; i++)
+  for (i=0; i<LED_BYTES; i++)
     leds[i] |= blinkleds[i];
 }
 
 void blink_leds_off(void) {
   uint8_t i;
 
-  for (i=0; i<5; i++)
+  for (i=0; i<LED_BYTES; i++)
     leds[i] &= ~blinkleds[i];
 }
 
 void clear_blinking_leds(void) {
   uint8_t i;
 
-  for (i=0; i<5; i++) {
+  for (i=0; i<LED_BYTES; i++) {
     if (leds[i] & blinkleds[i])
       leds[i] &= ~blinkleds[i];
     blinkleds[i] = 0;
Index: led.h
===================================================================
RCS file: /cvsroot/x0xb0x/firmware/led.h,v
retrieving revision 1.5
diff -u -r1.5 led.h
--- led.h	25 Apr 2005 05:17:11 -0000	1.5
+++ led.h	13 Jan 2006 13:19:05 -0000
@@ -37,9 +37,10 @@
 
 #define MAX_LED 40
 
-void clear_led(uint8_t ledno);
 void set_led(uint8_t ledno);
+void clear_led(uint8_t ledno);
 void set_led_blink(uint8_t ledno);
+void clear_led_blink(uint8_t ledno);
 
 int is_led_set(uint8_t ledno);
 uint8_t is_led_blink(uint8_t num);
@@ -47,7 +48,9 @@
 void set_bank_led(uint8_t num);
 void set_bank_led_blink(uint8_t num);
 void clear_bank_leds(void);
+void clear_bank_leds_blink(void);
 uint8_t is_bank_led_blink(uint8_t num);
+uint8_t is_bank_led_set(uint8_t num);
 
 void set_key_led(uint8_t num);
 void set_key_led_blink(uint8_t num);
@@ -58,8 +61,10 @@
 void set_numkey_led_blink(uint8_t num);
 void clear_numkey_leds(void);
 void clear_numkey_led(uint8_t num);
+void clear_numkey_led_blink(uint8_t num);
 uint8_t is_numkey_led_blink(uint8_t num);
 uint8_t is_numkey_led_set(uint8_t num);
+void set_single_numkey_led(uint8_t num);
 
 void set_notekey_led(uint8_t note);
 void set_notekey_led_blink(uint8_t num);
Index: midi.c
===================================================================
RCS file: /cvsroot/x0xb0x/firmware/midi.c,v
retrieving revision 1.6
diff -u -r1.6 midi.c
--- midi.c	6 Jun 2005 00:39:04 -0000	1.6
+++ midi.c	13 Jan 2006 13:19:05 -0000
@@ -63,6 +63,8 @@
 
 #define ACCENT_THRESH 100
 
+#define PREV_NOTE_OFF 255
+
 #define MIDI_Q_SIZE 32
 volatile uint8_t midi_q[MIDI_Q_SIZE];      // cyclic queue for midi msgs
 volatile static uint8_t head_idx = 0;
@@ -118,7 +120,8 @@
 void do_midi_mode(void) {
   char c;
   uint8_t last_bank;
-  uint8_t cmd, note, velocity;
+  uint8_t note, velocity;
+  //uint8_t cmd;
 
   // turn tempo off!
   turn_off_tempo();
@@ -129,7 +132,7 @@
 
   last_bank = bank;
 
-  prev_note = 255;        // no notes played yet
+  prev_note = PREV_NOTE_OFF;        // no notes played yet
 
   while (1) {
     read_switches();
@@ -170,6 +173,8 @@
 	  // not for us, continue!
 	  continue;
 	}
+      } else {
+	continue;  // no MIDI data waiting
       }
 
       switch (midi_running_status) {
@@ -244,25 +249,28 @@
 void midi_note_off(uint8_t note, uint8_t velocity) {
   if (note == prev_note) {
     note_off(0);
-    prev_note = 255;
+    clear_note_leds();
+    prev_note = PREV_NOTE_OFF;
   }
 }
 
 void midi_note_on(uint8_t note, uint8_t velocity) {
-  uint8_t slide = 0;
+  uint8_t slide  = FALSE;
+  uint8_t accent = FALSE;
 
   if (velocity == 0) {
     // strange midi thing: velocity 0 -> note off!
     midi_note_off(note, velocity);
   } else {
-    if (prev_note != 255)
-      slide = 1;
+    if (prev_note != PREV_NOTE_OFF) slide = TRUE;
+    if (velocity > ACCENT_THRESH)   accent = TRUE;
 
-    if (velocity > ACCENT_THRESH) {
-      note_on(note - 0x1A, slide, 1); // with accent
-    } else {
-      note_on(note - 0x1A, slide, 0); // no accent
-    }
+    note_on( from_midi_note(note), slide, accent);
+
+    // light relevant LEDs
+    set_note_led( from_midi_note(note) );
+    if (accent == TRUE) set_led(LED_ACCENT);
+    if (slide == TRUE)  set_led(LED_SLIDE);
 
     prev_note = note;
   }
@@ -274,7 +282,7 @@
   if ( (note & 0x3F) == 0)
     midi_putchar(0);                                 // rest
   else 
-    midi_putchar((note & 0x3F) + 0x19);              // note
+    midi_putchar( to_midi_note(note & 0x3F) );       // note
 
   if ((note >> 6) & 0x1)              // if theres an accent, give high velocity 
     midi_putchar(midion_accent_velocity);
@@ -288,7 +296,7 @@
   if ((note & 0x3F) == 0)
     midi_putchar(0);                                 // rest
   else 
-    midi_putchar((note & 0x3F) + 0x19);              // note
+    midi_putchar( to_midi_note(note & 0x3F) );       // note
 
 
   midi_putchar(midioff_velocity);                   // velocity
Index: midi.h
===================================================================
RCS file: /cvsroot/x0xb0x/firmware/midi.h,v
retrieving revision 1.6
diff -u -r1.6 midi.h
--- midi.h	11 May 2005 01:44:10 -0000	1.6
+++ midi.h	13 Jan 2006 13:19:05 -0000
@@ -51,6 +51,10 @@
 
 #define MIDISYNC_PPQ 24
 
+// map between MIDI note number and x0xb0x note number
+#define to_midi_note(note)   ((note) + 0x19)
+#define from_midi_note(note) ((note) - 0x19)
+
 int midi_putchar(char c);
 int midi_getch(void);
 int midi_getchar(void);
Index: pattern.h
===================================================================
RCS file: /cvsroot/x0xb0x/firmware/pattern.h,v
retrieving revision 1.2
diff -u -r1.2 pattern.h
--- pattern.h	24 Apr 2005 18:55:42 -0000	1.2
+++ pattern.h	13 Jan 2006 13:19:05 -0000
@@ -43,6 +43,9 @@
 void start_stepwrite_mode(void);
 void stop_stepwrite_mode(void);
 
+void start_pattsave_mode(void);
+void stop_pattsave_mode(void);
+
 uint8_t chains_equiv(volatile uint8_t *chain1, volatile uint8_t *chain2);
 
 #define NUM_BANKS 16
@@ -55,3 +58,26 @@
 
 #define END_OF_PATTERN 0xFF
 #define END_OF_CHAIN 0xFF
+
+#define DONE_NOTE 0x3F  // strip(END_OF_PATTERN)
+#define REST_NOTE 0x00
+
+// strip slide and accent from a note byte
+#ifndef strip
+#define strip(note)  ((note) & 0x3f)
+#endif
+
+// do note_on for full note byte (including accent and slide)
+#ifndef note_on_full
+#define note_on_full(note)  note_on((curr_note) & 0x3f,                  \
+                                    (curr_note) >> 7,       /* slide */  \
+                                    ((curr_note)>>6) & 0x1) /* accent */
+#endif
+
+#ifndef set_accent
+#define set_accent(note)  ((note) ^= 1 << 6)
+#endif
+
+#ifndef set_slide
+#define set_slide(note)   ((note) ^= 1 << 7)
+#endif
Index: pattern_edit.c
===================================================================
RCS file: /cvsroot/x0xb0x/firmware/pattern_edit.c,v
retrieving revision 1.7
diff -u -r1.7 pattern_edit.c
--- pattern_edit.c	25 Apr 2005 07:04:29 -0000	1.7
+++ pattern_edit.c	13 Jan 2006 13:19:06 -0000
@@ -54,7 +54,7 @@
 uint8_t patt_location, patt_bank;
 volatile uint8_t pattern_buff[PATT_SIZE];    // the 'loaded' pattern buffer
 
-uint8_t in_runwrite_mode, in_stepwrite_mode;
+uint8_t in_runwrite_mode, in_stepwrite_mode, in_pattsave_mode;
 
 extern uint8_t curr_note, sync;
 
@@ -64,9 +64,10 @@
 
   // initialize
   patt_location = 0;
-  in_stepwrite_mode = 0;
-  in_runwrite_mode = 0;
-  play_loaded_pattern = 0;
+  in_stepwrite_mode = FALSE;
+  in_runwrite_mode = FALSE;
+  in_pattsave_mode = FALSE;
+  play_loaded_pattern = FALSE;
   curr_pattern_index = 0;
   curr_note = 0;
   sync = INTERNAL_SYNC;
@@ -107,7 +108,9 @@
       if (in_stepwrite_mode)
 	stop_stepwrite_mode();
       patt_bank = bank;
-      load_pattern(patt_bank, patt_location);
+      if (!in_pattsave_mode) {
+	load_pattern(patt_bank, patt_location);
+      }
       clear_bank_leds();
       set_bank_led(bank);
     }
@@ -122,7 +125,9 @@
 	clear_notekey_leds();
 	set_numkey_led(i);
 	patt_location = i - 1;
-	load_pattern(patt_bank, patt_location);
+	if (!in_pattsave_mode) {
+	  load_pattern(patt_bank, patt_location);
+	}
 	//printf("location #%d\n\r", patt_location);
       }
     }
@@ -141,6 +146,11 @@
     // if they hit run/stop, play the pattern in scratch! 
     // (until they hit rs again)
     if (just_pressed(KEY_RS)) {
+      if (in_pattsave_mode) {
+	// cancel save operation
+	stop_pattsave_mode();
+      }
+
       if (in_runwrite_mode) {
 	stop_runwrite_mode();
       } else if (in_stepwrite_mode) {
@@ -159,20 +169,20 @@
 
       index = curr_pattern_index;
 
-      curr_note = pattern_buff[index] & 0x3F;
+      curr_note = strip( pattern_buff[index] );
       
       // dont accent or slide 'done' notes, duh!
-      if (just_pressed(KEY_ACCENT) && (curr_note != 0x3F)) {
+      if (just_pressed(KEY_ACCENT) && (curr_note != DONE_NOTE)) {
 	//putstring("accent ");
-	pattern_buff[index] ^= 1 << 6;
+	set_accent( pattern_buff[index] );
       }
-      if (just_pressed(KEY_SLIDE) && (curr_note != 0x3F)) {
+      if (just_pressed(KEY_SLIDE) && (curr_note != DONE_NOTE)) {
 	//putstring("slide ");
-      	pattern_buff[index] ^= 1 << 7;
+      	set_slide( pattern_buff[index] );
       }
 
       // rests/dones are middle octave (if you hit a note key next)
-      if ((curr_note == 0x3F) || (curr_note == 0)) 
+      if ((curr_note == DONE_NOTE) || (curr_note == REST_NOTE)) 
 	shift = 0;
       else if (curr_note < C2)
 	shift = -1;
@@ -186,18 +196,18 @@
 	shift = 3;
 
       if (just_pressed(KEY_REST)) {
-	curr_note = 0;
+	curr_note = REST_NOTE;
       }
       
       // cant change octaves on rest/done
       if (just_pressed(KEY_UP) &&       
-	  (curr_note != 0x3F) && (curr_note != 0))
+	  (curr_note != DONE_NOTE) && (curr_note != REST_NOTE))
 	if (shift < 1)
 	  curr_note += OCTAVE;
 
       // cant change octaves on rest/done, but default to mid octave
       if (just_pressed(KEY_DOWN) &&
-	  (curr_note != 0x3F) && (curr_note != 0))
+	  (curr_note != DONE_NOTE) && (curr_note != REST_NOTE))
 	if (shift > -1)
 	  curr_note -= OCTAVE;
 
@@ -234,7 +244,7 @@
       }
 
       // when changing to a note from end of pattern (0xff), toss top 2 bits
-      if ((pattern_buff[index] != 0xFF) || (curr_note == 0x3F))
+      if ((pattern_buff[index] != END_OF_PATTERN) || (curr_note == DONE_NOTE))
 	curr_note |= (pattern_buff[index] & 0xC0);   
 
       if (curr_note != pattern_buff[index]) {
@@ -246,9 +256,7 @@
 	pattern_buff[index] = curr_note;
 
 	if (in_stepwrite_mode) 	 // restrike note
-	  note_on(curr_note & 0x3F,
-		  curr_note >> 7,              // slide
-		  (curr_note>>6) & 0x1);       // accent
+	  note_on_full(curr_note);
 	
       }
       if (curr_note != 0xFF) {
@@ -301,10 +309,8 @@
 	  set_led(LED_DONE);
 	} else {
 	  clear_led(LED_DONE);
-	  note_on(curr_note & 0x3F,
-		  curr_note >> 7,              // slide
-		  (curr_note>>6) & 0x1);       // accent
-	  
+	  note_on_full(curr_note);
+
 	  set_note_led(curr_note);
 	}
       } else if (just_pressed(KEY_NEXT) && !in_runwrite_mode) {
@@ -314,9 +320,7 @@
 
 	curr_note = pattern_buff[curr_pattern_index];
 	if (curr_note != 0xFF) {
-	  note_on(curr_note & 0x3F,
-		  curr_note >> 7,              // slide
-		  (curr_note>>6) & 0x1);       // accent
+	  note_on_full(curr_note);
 	  
 	  set_note_led(curr_note);
 	}
@@ -331,12 +335,26 @@
 	for (i = curr_pattern_index + 1; i < PATT_SIZE; i++)
 	  pattern_buff[i] = 0xFF;
 	*/
+	// put sentinel marker in, pattern is less than 16 steps
 	if (curr_pattern_index+1 < PATT_SIZE)
-	  pattern_buff[curr_pattern_index+1] = 0xff;
+	  pattern_buff[curr_pattern_index+1] = END_OF_PATTERN;
 
 	stop_stepwrite_mode();
       }
-      write_pattern(bank, patt_location);
+
+      if (in_runwrite_mode) {
+	// sorry, we need to stop so they can select bank/loc
+	stop_runwrite_mode();
+      }
+
+      if (in_pattsave_mode) {
+	// hit DONE the second time
+	write_pattern(bank, patt_location);
+	stop_pattsave_mode();
+      } else {
+	// hit DONE the first time
+	start_pattsave_mode();
+      }
     }
 
 
@@ -365,6 +383,13 @@
   }
   //putstring("\n\r");
 
+  if (pattern_buff[0] == END_OF_PATTERN) {
+    // empty pattern, default to all notes middle C, 16 steps
+    for (i=0; i<PATT_SIZE; i++) {
+      pattern_buff[i] = C2;
+    }
+  }
+
   clock_leds();
 
 }
@@ -410,22 +435,22 @@
 void start_runwrite_mode() {
   //putstring("start runwrite\n\r");
   curr_pattern_index = 0;
-  in_runwrite_mode = 1;
+  in_runwrite_mode = TRUE;
   set_led(LED_RS); 
   note_off(0);
   turn_on_tempo();
   while (note_counter & 0x1);  // wait for the tempo interrupt to be ready for a note-on
-  play_loaded_pattern = 1;
+  play_loaded_pattern = TRUE;
 }
 
 void stop_runwrite_mode() {
   //putstring("stop runwrite\n\r");
   turn_off_tempo();
-  play_loaded_pattern = 0;
+  play_loaded_pattern = FALSE;
   clear_key_leds();
   clear_bank_leds();
   set_bank_led(bank);
-  in_runwrite_mode = 0;
+  in_runwrite_mode = FALSE;
   clear_led(LED_RS);
   note_off(0);
 }
@@ -435,7 +460,7 @@
 
 void start_stepwrite_mode() {
   //putstring("start stepwrite\n\r");
-  in_stepwrite_mode = 1;
+  in_stepwrite_mode = TRUE;
   set_led(LED_NEXT); 
   clear_bank_leds();
   set_bank_led(0);
@@ -445,7 +470,7 @@
 
 void stop_stepwrite_mode() {
   //putstring("stop stepwrite\n\r");
-  in_stepwrite_mode = 0;
+  in_stepwrite_mode = FALSE;
   clear_led(LED_NEXT); 
   clear_key_leds();
   clear_bank_leds();
@@ -453,3 +478,24 @@
   turn_on_tempo();
   note_off(0);
 }
+
+
+
+void start_pattsave_mode(void) {
+  //putstring("start pattsave\n\r");
+  in_pattsave_mode = TRUE;
+  turn_on_tempo();  // to enable blinking LEDs
+  note_off(0);
+  clear_key_leds();
+  set_led_blink(LED_DONE);
+  set_bank_led(bank);
+  set_numkey_led(patt_location+1);
+}
+
+void stop_pattsave_mode(void) {
+  //putstring("stop pattsave\n\r");
+  in_pattsave_mode = FALSE;
+  clear_led_blink(LED_DONE);
+  clear_key_leds();
+  clear_bank_leds();
+}
Index: pattern_play.c
===================================================================
RCS file: /cvsroot/x0xb0x/firmware/pattern_play.c,v
retrieving revision 1.7
diff -u -r1.7 pattern_play.c
--- pattern_play.c	25 Apr 2005 07:04:29 -0000	1.7
+++ pattern_play.c	13 Jan 2006 13:19:06 -0000
@@ -93,7 +93,7 @@
 void do_patterntrack_play(void) {
   uint8_t i = 0, curr_function;
   uint8_t midi_cmd = 0;
-  uint8_t midi_data = 0;
+  //uint8_t midi_data = 0;
 
   curr_function = function;
 

