///////////////////////////////////////////////////////////////////////// //// HammondWith4051s.c //// //// //// This program scans up to 512 input from the Hammond Commodore //// organ and outputs MIDI in response. ///////////////////////////////////////////////////////////////////////// #include <16F877A.h> #fuses HS,NOPROTECT,NOWDT //#define HOLD_OFF 500 //#define PEAK20 25 //#define PEAK40 38 //#define PEAK50 50 //#define PEAK60 55 #define TopManualLowCNoteNumber 36 #define TopManualMIDIChannel 1 #define BottomManualLowCNoteNumber 36 #define BottomManualMIDIChannel 2 #define PedalboardLowCNoteNumber 24 #define PedalboardMIDIChannel 3 #use fast_io(a) #use fast_io(b) #use fast_io(c) #use fast_io(d) #use fast_io(e) #use delay(clock=20000000) #use rs232(baud=31250,xmit=PIN_C6,rcv=PIN_C7) /* DEFINE EQUATES FOR PORTS */ #byte PORTA = 5 #byte PORTB = 6 #byte PORTC = 7 #byte PORTD = 8 #byte PORTE = 9 void main() { // unsigned action, i, value, softtime, dispval; int b, NoteNum, Connector, Address; short TopManualKeyState[70]; // Each element is 1 bit indicating the state of that // numbered button on the last scan. short BottomManualKeyState[70]; // Each element is 1 bit indicating the state of that // numbered button on the last scan. short BassPedalState[33]; // Each element is 1 bit indicating the state of that // numbered button on the last scan. disable_interrupts(GLOBAL); setup_port_a( NO_ANALOGS ); // setup_adc( ADC_CLOCK_DIV_32 ); setup_timer_1 (T1_INTERNAL | T1_DIV_BY_1); set_tris_a( 0XFF ); /* ALL INPUTS */ set_tris_b( 0X03 ); /* b0-b1 = INPUT b2-b7 OUTPUT*/ // set_tris_c( 0X90 ); /* c4, c7 = INPUT, c0-c3, c5-c6 = OUTPUT */ set_tris_c( 0X9F ); /* c0-c4, c7 = INPUT, c5-c6 = OUTPUT */ set_tris_d( 0X00 ); /* ALL OUTPUTS */ set_tris_e( 0X07 ); /* e0-2 = INPUT (ONLY 3 PINS AVAILABLE */ // set_adc_channel( 0 ); // delay_us(20); // Zero out the TopManualKeyState array. for (b=0; b<70; b++) { TopManualKeyState[b] = 0; } // Zero out the BottomManualKeyState array. for (b=0; b<70; b++) { BottomManualKeyState[b] = 0; } do { for (Connector=0; Connector<=2; Connector++) { // Scan through all the connectors for (b=0; b<=15; b++) { // Scan through all the groups of 4 inputs on this connector // Output the select bits for the 4051 & 4067 analog mux chips. Address = (16 * Connector) + b; output_d(Address); // Wait for input to settle delay_us(10); if (Connector == 0) { //Top Manual // Input C0 = Top Manual Keys 1-16 if ((input(PIN_C0)==1) && (TopManualKeyState[b]==0)) { // It has gone from low to high since last time NoteNum = TopManualLowCNoteNumber + b; putc(0x90); // Note On message on Channel 1 putc(NoteNum); putc(0x40); // Velocity = 64 TopManualKeyState[b] = 1; } if ((input(PIN_C0)==0) && (TopManualKeyState[b]==1)) { // It has gone from high to low since last time NoteNum = TopManualLowCNoteNumber + b; putc(0x90); // Note Off message (Note On Velocity 0) on Channel 1 putc(NoteNum); putc(0x00); // Velocity = 0 TopManualKeyState[b] = 0; } // Input C1 = Top Manual Keys 17-32 if ((input(PIN_C1)==1) && (TopManualKeyState[b+16]==0)) { // It has gone from low to high since last time NoteNum = TopManualLowCNoteNumber + b + 16; putc(0x90); // Note On message on Channel 1 putc(NoteNum); putc(0x40); // Velocity = 64 TopManualKeyState[b+16] = 1; } if ((input(PIN_C1)==0) && (TopManualKeyState[b+16]==1)) { // It has gone from high to low since last time NoteNum = TopManualLowCNoteNumber + b + 16; putc(0x90); // Note Off message (Note On Velocity 0) on Channel 1 putc(NoteNum); putc(0x00); // Velocity = 0 TopManualKeyState[b+16] = 0; } // Input C2 = Top Manual Keys 33-48 if ((input(PIN_C2)==1) && (TopManualKeyState[b+32]==0)) { // It has gone from low to high since last time NoteNum = TopManualLowCNoteNumber + b + 32; putc(0x90); // Note On message on Channel 1 putc(NoteNum); putc(0x40); // Velocity = 64 TopManualKeyState[b+32] = 1; } if ((input(PIN_C2)==0) && (TopManualKeyState[b+32]==1)) { // It has gone from high to low since last time NoteNum = TopManualLowCNoteNumber + b + 32; putc(0x90); // Note Off message (Note On Velocity 0) on Channel 1 putc(NoteNum); putc(0x00); // Velocity = 0 TopManualKeyState[b+32] = 0; } // Input C3 = Top Manual Keys 49-64 if ((input(PIN_C3)==1) && (TopManualKeyState[b+48]==0)) { // It has gone from low to high since last time NoteNum = TopManualLowCNoteNumber + b + 48; putc(0x90); // Note On message on Channel 1 putc(NoteNum); putc(0x40); // Velocity = 64 TopManualKeyState[b+48] = 1; } if ((input(PIN_C3)==0) && (TopManualKeyState[b+48]==1)) { // It has gone from high to low since last time NoteNum = TopManualLowCNoteNumber + b + 48; putc(0x90); // Note Off message (Note On Velocity 0) on Channel 1 putc(NoteNum); putc(0x00); // Velocity = 0 TopManualKeyState[b+48] = 0; } } if (Connector == 1) { //Bottom Manual // Input C0 = Bottom Manual Keys 1-16 if ((input(PIN_C0)==1) && (BottomManualKeyState[b]==0)) { // It has gone from low to high since last time NoteNum = BottomManualLowCNoteNumber + b; putc(0x91); // Note On message on Channel 2 putc(NoteNum); putc(0x40); // Velocity = 64 BottomManualKeyState[b] = 1; } if ((input(PIN_C0)==0) && (BottomManualKeyState[b]==1)) { // It has gone from high to low since last time NoteNum = BottomManualLowCNoteNumber + b; putc(0x91); // Note Off message (Note On Velocity 0) Channel 2 putc(NoteNum); putc(0x00); // Velocity = 0 BottomManualKeyState[b] = 0; } // Input C1 = Bottom Manual Keys 17-32 if ((input(PIN_C1)==1) && (BottomManualKeyState[b+16]==0)) { // It has gone from low to high since last time NoteNum = BottomManualLowCNoteNumber + b + 16; putc(0x91); // Note On message on Channel 2 putc(NoteNum); putc(0x40); // Velocity = 64 BottomManualKeyState[b+16] = 1; } if ((input(PIN_C1)==0) && (BottomManualKeyState[b+16]==1)) { // It has gone from high to low since last time NoteNum = BottomManualLowCNoteNumber + b + 16; putc(0x91); // Note Off message (Note On Velocity 0) on Channel 2 putc(NoteNum); putc(0x00); // Velocity = 0 BottomManualKeyState[b+16] = 0; } // Input C2 = Bottom Manual Keys 33-48 if ((input(PIN_C2)==1) && (BottomManualKeyState[b+32]==0)) { // It has gone from low to high since last time NoteNum = BottomManualLowCNoteNumber + b + 32; putc(0x91); // Note On message on Channel 2 putc(NoteNum); putc(0x40); // Velocity = 64 BottomManualKeyState[b+32] = 1; } if ((input(PIN_C2)==0) && (BottomManualKeyState[b+32]==1)) { // It has gone from high to low since last time NoteNum = BottomManualLowCNoteNumber + b + 32; putc(0x91); // Note Off message (Note On Velocity 0) on Channel 2 putc(NoteNum); putc(0x00); // Velocity = 0 BottomManualKeyState[b+32] = 0; } // Input C3 = Bottom Manual Keys 49-64 if ((input(PIN_C3)==1) && (BottomManualKeyState[b+48]==0)) { // It has gone from low to high since last time NoteNum = BottomManualLowCNoteNumber + b + 48; putc(0x91); // Note On message on Channel 2 putc(NoteNum); putc(0x40); // Velocity = 64 BottomManualKeyState[b+48] = 1; } if ((input(PIN_C3)==0) && (BottomManualKeyState[b+48]==1)) { // It has gone from high to low since last time NoteNum = BottomManualLowCNoteNumber + b + 48; putc(0x91); // Note Off message (Note On Velocity 0) Channel 2 putc(NoteNum); putc(0x00); // Velocity = 0 BottomManualKeyState[b+48] = 0; } } if (Connector == 2) { //Bass Pedals // Input C0 = Bass Pedals 1-16 if ((input(PIN_C0)==1) && (BassPedalState[b]==0)) { // It has gone from low to high since last time NoteNum = PedalboardLowCNoteNumber + b; putc(0x92); // Note On message on Channel 3 putc(NoteNum); putc(0x40); // Velocity = 64 BassPedalState[b] = 1; } if ((input(PIN_C0)==0) && (BassPedalState[b]==1)) { // It has gone from high to low since last time NoteNum = PedalboardLowCNoteNumber + b; putc(0x92); // Note Off message (Note On Velocity 0) on Channel 3 putc(NoteNum); putc(0x00); // Velocity = 0 BassPedalState[b] = 0; } // Input C1 = Bass Pedals 17-32 if ((input(PIN_C1)==1) && (BassPedalState[b+16]==0)) { // It has gone from low to high since last time NoteNum = PedalboardLowCNoteNumber + b + 16; putc(0x92); // Note On message on Channel 3 putc(NoteNum); putc(0x40); // Velocity = 64 BassPedalState[b+16] = 1; } if ((input(PIN_C1)==0) && (BassPedalState[b+16]==1)) { // It has gone from high to low since last time NoteNum = PedalboardLowCNoteNumber + b + 16; putc(0x92); // Note Off message (Note On Velocity 0) on Channel 3 putc(NoteNum); putc(0x00); // Velocity = 0 BassPedalState[b+16] = 0; } } } } } while (TRUE); }