PSUEDOCODE
==========

'----------------------------
'  Synchronia--Duet 0.0.7
' (C)2018 Thomas R. Mahanna
'----------------------------

'CONFIGURE HARDWARE I/O (ATMEGA2560 in the Case of the Prototype)

'Configure Communication

Open Serial1 For Binary As #0		'Serial Connection to PC
Open Serial2 For Binary As #1           'MIDI Out / QUNexus In
Open Serial3 For Binary As #2           'UNZTRUMENT I/O

'DIMESION VARIABLES

'Serial Input Variables

Dim SerialInbyte As Byte
Dim SerialFlag As Bit
Dim QuNexusInbyte As Byte
Dim QuNexusFlag As Bit
Dim UntzInbyte As Byte
Dim UntzFlag As Bit

'MIDI Variables

Dim MIDICh as byte
Dim Timbre as Byte
Dim Status As Byte
Dim Data1 As Byte
Dim Data2 As Byte
Dim StrumDelay As Byte
Dim ChordArray(4) as Byte
Dim ScaleArray(5) as Byte
Dim Vel as Byte
Dim Pedal as bit
Dim Notes(5) as Byte

'Main Variables

Dim I As Byte
Dim ChordType As Byte
Dim OldChord As Byte
Dim Root As Byte
Dim OldRoot As Byte
Dim OldChordButton As Byte
Dim OldRootButton As Byte
Dim ButtonHold As Bit
Dim Offset as Byte
Dim Temp as byte

'DEFINE IRQ HANDLERS

On Serial1 PCSerial_isr
On Serial2 Qunexus_isr
On Serial3 Untz_isr

'ENABLE INTERRUPTS

Enable IRQ0
Enable IRQ1
Enable IRQ2
Enable Global Interrupts

'DEFINE / DECLARE SUBROUTINES

Declare Sub Midiout(byval Ch As Byte , Byval Note As Byte , Byval Vel As Byte)
Declare Sub Midipatch(byval Ch As Byte , Byval Patch As Byte)
Declare Sub Mastervolume(byval Vol As Byte)
Declare Sub Allnotesoff
Declare Sub ProcessUntzButton

'MAIN

' Entering Main Loop

For I = 0 To 15
   SerialOut #2 , I                      'All Chord Buttons Off
   Waitms 1
Next

For I = 76 To 79
   SerialOut #2 , I
   Waitms 1
Next

For I = 92 To 95
  SerialOut #2 , I
  Waitms 1
Next

For I = 108 To 111
   SerialOut #2 , I                      'All Trellis Root Buttons Off
   Waitms 1
Next

Chordtype = 0
SerialOut #2 , 140
OldChordButton = 12

Root = 0
SerialOut #2 , 204
OldRootButton = 76
Offset = 48                             'Octave 4 * 12

Call ProcessUntzButton

MIDICh = 1                              'Set MIDI Output Channel
Timbre = 0                              'GM Piano [0]
Vel = 96                                'Velocity
StrumDelay = 40                         'Spread Between Notes (mS)
Pedal = 1                               'Pedal off

SerialOut #1 , &HB0
SerialOut #1 , &H7B
SerialOut #1 , &H00                      'All Notes Off

SerialOut #1 , 176
SerialOut #1 , 7
SerialOut #1 , 64                        'Set Volume to 96

Call Mastervolume(64)                   'Set Volume to 96
Call Midipatch(midich , Timbre)         'Change MIDI Intrument Timbre

Do
   '// PROCESS UNTZTRUMENT
   If UntzFlag = 1 Then
      Select Case UntzInbyte

      '// Button Release
            Case 12
               ButtonHold = 0
            Case 13
               ButtonHold = 0
            Case 14
               ButtonHold = 0
            Case 15
               ButtonHold = 0

            Case 16 to 127
               If Pedal = 0 then
                  Call MIDIOut(MIDICh , ChordArray(1) , 0)
                  Call MIDIOut(MIDICh , ChordArray(2) , 0)
                  Call MIDIOut(MIDICh , ChordArray(3) , 0)
                  Call MIDIOut(MIDICh , ChordArray(4) , 0)
               End If

      '// Chord Selection
           Case 140
               Chordtype = 0            'Major
               SerialOut #2 , OldChordButton       'Turn old chordtype button off
               SerialOut #2 , UntzInbyte 'Turn new chordtype button on
                If UntzInbyte > 127 Then
                  OldChordButton = UntzInbyte - 128
               Else
                  OldChordButton = UntzInbyte
               End If
               Buttonhold = 1
               Call ProcessUntzButton
           Case 141
               Chordtype = 1            'Minor
               SerialOut #2 , OldChordButton       'Turn old chordtype button off
               SerialOut #2 , UntzInbyte 'Turn new chordtype button on
               If UntzInbyte > 127 Then
                  OldChordButton = UntzInbyte - 128
               Else
                  OldChordButton = UntzInbyte
               End If
               Buttonhold = 1
           Case 142
               Chordtype = 2            'Sus4
               SerialOut #2 , OldChordButton       'Turn old chordtype button off
               SerialOut #2 , UntzInbyte 'Turn new chordtype button on
               If UntzInbyte > 127 Then
                  OldChordButton = UntzInbyte - 128
               Else
                  OldChordButton = UntzInbyte
               End If
               Buttonhold = 1
           Case 143
               Chordtype = 3            'Dom7
               SerialOut #2 , OldChordButton       'Turn old chordtype button off
               SerialOut #2 , UntzInbyte 'Turn new chordtype button on
               If UntzInbyte > 127 Then
                  OldChordButton = UntzInbyte - 128
               Else
                  OldChordButton = UntzInbyte
               End If
               Buttonhold = 1

           '// Root Selection
           Case 204
               SerialOut #2 , OldRootButton       'Turn old root button off
               SerialOut #2 , UntzInbyte 'Turn new root button on
               Root = 0                 'Root C
               Call ProcessUntzButton
               If ButtonHold = 1 Then
                  Call MIDIOut(MIDICh , ChordArray(1) , Vel)
                  waitms StrumDelay
                  Call MIDIOut(MIDICh , ChordArray(2) , Vel)
                  waitms StrumDelay
                  Call MIDIOut(MIDICh , ChordArray(3) , Vel)
                  waitms StrumDelay
                  Call MIDIOut(MIDICh , ChordArray(4) , Vel)
                  waitms StrumDelay
               End If
               If UntzInbyte > 127 Then
                  OldRootButton = UntzInbyte - 128
               Else
                  OldRootButton = UntzInbyte
               End If
         Case 205
               SerialOut #2 , OldRootButton       'Turn old root button off
               SerialOut #2 , UntzInbyte 'Turn new root button on
               Root = 1                 'Root C#
               Call ProcessUntzButton
               If ButtonHold = 1 Then
                  Call MIDIOut(MIDICh , ChordArray(1) , Vel)
                  waitms StrumDelay
                  Call MIDIOut(MIDICh , ChordArray(2) , Vel)
                  waitms StrumDelay
                  Call MIDIOut(MIDICh , ChordArray(3) , Vel)
                  waitms StrumDelay
                  Call MIDIOut(MIDICh , ChordArray(4) , Vel)
                  waitms StrumDelay
               End If
               If UntzInbyte > 127 Then
                  OldRootButton = UntzInbyte - 128
               Else
                  OldRootButton = UntzInbyte
               End If
         Case 206
               SerialOut #2 , OldRootButton       'Turn old root button off
               SerialOut #2 , UntzInbyte 'Turn new root button on
               Root = 2                 'Root D
               Call ProcessUntzButton
               If ButtonHold = 1 Then
                  Call MIDIOut(MIDICh , ChordArray(1) , Vel)
                  waitms StrumDelay
                  Call MIDIOut(MIDICh , ChordArray(2) , Vel)
                  waitms StrumDelay
                  Call MIDIOut(MIDICh , ChordArray(3) , Vel)
                  waitms StrumDelay
                  Call MIDIOut(MIDICh , ChordArray(4) , Vel)
                  waitms StrumDelay
               End If
               If UntzInbyte > 127 Then
                  OldRootButton = UntzInbyte - 128
               Else
                  OldRootButton = UntzInbyte
               End If
         Case 207
               SerialOut #2 , OldRootButton       'Turn old root button off
               SerialOut #2 , UntzInbyte 'Turn new root button on
               Root = 3                 'Root D#
               Call ProcessUntzButton
               If ButtonHold = 1 Then
                  Call MIDIOut(MIDICh , ChordArray(1) , Vel)
                  waitms StrumDelay
                  Call MIDIOut(MIDICh , ChordArray(2) , Vel)
                  waitms StrumDelay
                  Call MIDIOut(MIDICh , ChordArray(3) , Vel)
                  waitms StrumDelay
                  Call MIDIOut(MIDICh , ChordArray(4) , Vel)
                  waitms StrumDelay
               End If
               If UntzInbyte > 127 Then
                  OldRootButton = UntzInbyte - 128
               Else
                  OldRootButton = UntzInbyte
               End If
         Case 220
               SerialOut #2 , OldRootButton       'Turn old root button off
               SerialOut #2 , UntzInbyte 'Turn new root button on
               Root = 4                 'Root E
               Call ProcessUntzButton
               If ButtonHold = 1 Then
                  Call MIDIOut(MIDICh , ChordArray(1) , Vel)
                  waitms StrumDelay
                  Call MIDIOut(MIDICh , ChordArray(2) , Vel)
                  waitms StrumDelay
                  Call MIDIOut(MIDICh , ChordArray(3) , Vel)
                  waitms StrumDelay
                  Call MIDIOut(MIDICh , ChordArray(4) , Vel)
                  waitms StrumDelay
               End If
               If UntzInbyte > 127 Then
                  OldRootButton = UntzInbyte - 128
               Else
                  OldRootButton = UntzInbyte
               End If
         Case 221
               SerialOut #2 , OldRootButton       'Turn old root button off
               SerialOut #2 , UntzInbyte 'Turn new root button on
               Root = 5                 'Root F
               Call ProcessUntzButton
               If ButtonHold = 1 Then
                  Call MIDIOut(MIDICh , ChordArray(1) , Vel)
                  waitms StrumDelay
                  Call MIDIOut(MIDICh , ChordArray(2) , Vel)
                  waitms StrumDelay
                  Call MIDIOut(MIDICh , ChordArray(3) , Vel)
                  waitms StrumDelay
                  Call MIDIOut(MIDICh , ChordArray(4) , Vel)
                  waitms StrumDelay
               End If
               If UntzInbyte > 127 Then
                  OldRootButton = UntzInbyte - 128
               Else
                  OldRootButton = UntzInbyte
               End If
         Case 222
               SerialOut #2 , OldRootButton       'Turn old root button off
               SerialOut #2 , UntzInbyte 'Turn new root button on
               Root = 6                 'Root F#
               Call ProcessUntzButton
               If ButtonHold = 1 Then
                  Call MIDIOut(MIDICh , ChordArray(1) , Vel)
                  waitms StrumDelay
                  Call MIDIOut(MIDICh , ChordArray(2) , Vel)
                  waitms StrumDelay
                  Call MIDIOut(MIDICh , ChordArray(3) , Vel)
                  waitms StrumDelay
                  Call MIDIOut(MIDICh , ChordArray(4) , Vel)
                  waitms StrumDelay
               End If
               If UntzInbyte > 127 Then
                  OldRootButton = UntzInbyte - 128
               Else
                  OldRootButton = UntzInbyte
               End If
         Case 223
               SerialOut #2 , OldRootButton       'Turn old root button off
               SerialOut #2 , UntzInbyte 'Turn new root button on
               Root = 7                 'Root G
               Call ProcessUntzButton
               If ButtonHold = 1 Then
                  Call MIDIOut(MIDICh , ChordArray(1) , Vel)
                  waitms StrumDelay
                  Call MIDIOut(MIDICh , ChordArray(2) , Vel)
                  waitms StrumDelay
                  Call MIDIOut(MIDICh , ChordArray(3) , Vel)
                  waitms StrumDelay
                  Call MIDIOut(MIDICh , ChordArray(4) , Vel)
                  waitms StrumDelay
               End If
               If UntzInbyte > 127 Then
                  OldRootButton = UntzInbyte - 128
               Else
                  OldRootButton = UntzInbyte
               End If
               'Print "Root  = G"
         Case 236
               SerialOut #2 , OldRootButton       'Turn old root button off
               SerialOut #2 , UntzInbyte 'Turn new root button on
               Root = 8                 'Root G#
               Call ProcessUntzButton
               If ButtonHold = 1 Then
                  Call MIDIOut(MIDICh , ChordArray(1) , Vel)
                  waitms StrumDelay
                  Call MIDIOut(MIDICh , ChordArray(2) , Vel)
                  waitms StrumDelay
                  Call MIDIOut(MIDICh , ChordArray(3) , Vel)
                  waitms StrumDelay
                  Call MIDIOut(MIDICh , ChordArray(4) , Vel)
                  waitms StrumDelay
               End If
               If UntzInbyte > 127 Then
                  OldRootButton = UntzInbyte - 128
               Else
                  OldRootButton = UntzInbyte
               End If
         Case 237
               SerialOut #2 , OldRootButton       'Turn old root button off
               SerialOut #2 , UntzInbyte 'Turn new root button on
               Root = 9                 'Root A
               Call ProcessUntzButton
               If ButtonHold = 1 Then
                  Call MIDIOut(MIDICh , ChordArray(1) , Vel)
                  waitms StrumDelay
                  Call MIDIOut(MIDICh , ChordArray(2) , Vel)
                  waitms StrumDelay
                  Call MIDIOut(MIDICh , ChordArray(3) , Vel)
                  waitms StrumDelay
                  Call MIDIOut(MIDICh , ChordArray(4) , Vel)
                  waitms StrumDelay
               End If
               If UntzInbyte > 127 Then
                  OldRootButton = UntzInbyte - 128
               Else
                  OldRootButton = UntzInbyte
               End If
         Case 238
               SerialOut #2 , OldRootButton       'Turn old root button off
               SerialOut #2 , UntzInbyte 'Turn new root button on
               Root = 10                'Root A#
               Call ProcessUntzButton
               If ButtonHold = 1 Then
                  Call MIDIOut(MIDICh , ChordArray(1) , Vel)
                  waitms StrumDelay
                  Call MIDIOut(MIDICh , ChordArray(2) , Vel)
                  waitms StrumDelay
                  Call MIDIOut(MIDICh , ChordArray(3) , Vel)
                  waitms StrumDelay
                  Call MIDIOut(MIDICh , ChordArray(4) , Vel)
                  waitms StrumDelay
               End If
               If UntzInbyte > 127 Then
                  OldRootButton = UntzInbyte - 128
               Else
                  OldRootButton = UntzInbyte
               End If
         Case 239
               SerialOut #2 , OldRootButton       'Turn old root button off
               SerialOut #2 , UntzInbyte 'Turn new root button on
               Root = 11                'Root B
               Call ProcessUntzButton
               If ButtonHold = 1 Then
                  Call MIDIOut(MIDICh , ChordArray(1) , Vel)
                  waitms StrumDelay
                  Call MIDIOut(MIDICh , ChordArray(2) , Vel)
                  waitms StrumDelay
                  Call MIDIOut(MIDICh , ChordArray(3) , Vel)
                  waitms StrumDelay
                  Call MIDIOut(MIDICh , ChordArray(4) , Vel)
                  waitms StrumDelay
               End If
               If UntzInbyte > 127 Then
                  OldRootButton = UntzInbyte - 128
               Else
                  OldRootButton = UntzInbyte
               End If
         End Select
      UntzFlag = 0
  End If

 '// PROCESS QUNEXUS
   If QuNexusFlag = 1 Then
      If Data2 > 0 then
         Select Case Data1
         '// Process White Keys
            Case 48
               Temp = ChordArray(1) - 12
            Case 50
               Temp = ChordArray(2) - 12
            Case 52
               Temp = ChordArray(3) - 12
            Case 53
               Temp = ChordArray(4) - 12

            Case 55
               Temp = ChordArray(1)
            Case 57
               Temp = ChordArray(2)
            Case 59
               Temp = ChordArray(3)
            Case 60
               Temp = ChordArray(4)

            Case 62
               Temp = ChordArray(1) + 12
            Case 64
               Temp = ChordArray(2) + 12
            Case 65
               Temp = ChordArray(3) + 12
            Case 67
               Temp = ChordArray(4) + 12

            Case 69
               Temp = ChordArray(1) + 24
            Case 71
               Temp = ChordArray(2) + 24
            Case 72
               Temp = ChordArray(3) + 24

      '// Process Blue Keys
            Case 49
               Temp = ScaleArray(1)
            Case 51
               Temp = ScaleArray(2)
            Case 54
               Temp = ScaleArray(3)
            Case 56
               Temp = ScaleArray(4)
            Case 58
               Temp = ScaleArray(5)

            Case 61
               Temp = ScaleArray(1) + 12
            Case 63
               Temp = ScaleArray(2) + 12
            Case 66
               Temp = ScaleArray(3) + 12
            Case 68
               Temp = ScaleArray(4) + 12
            Case 70
               Temp = ScaleArray(5) + 12
         End Select

         Call MidiOut(MIDICh , Temp , Vel)

         Else
            If Pedal = 0 Then
               Select Case Data1
               '// Process White Keys
                  Case 48
                     Temp = ChordArray(1) - 12
                  Case 50
                     Temp = ChordArray(2) - 12
                  Case 52
                     Temp = ChordArray(3) - 12
                  Case 53
                     Temp = ChordArray(4) - 12

                  Case 55
                     Temp = ChordArray(1)
                  Case 57
                     Temp = ChordArray(2)
                  Case 59
                     Temp = ChordArray(3)
                  Case 60
                     Temp = ChordArray(4)

                  Case 62
                     Temp = ChordArray(1) + 12
                  Case 64
                     Temp = ChordArray(2) + 12
                  Case 65
                     Temp = ChordArray(3) + 12
                  Case 67
                      Temp = ChordArray(4) + 12

                  Case 69
                     Temp = ChordArray(1) + 24
                  Case 71
                     Temp = ChordArray(2) + 24
                  Case 72
                     Temp = ChordArray(3) + 24

             '// Process Blue Keys
                  Case 49
                     Temp = ScaleArray(1)
                  Case 51
                     Temp = ScaleArray(2)
                  Case 54
                     Temp = ScaleArray(3)
                  Case 56
                     Temp = ScaleArray(4)
                  Case 58
                     Temp = ScaleArray(5)

                  Case 61
                     Temp = ScaleArray(1) + 12
                  Case 63
                     Temp = ScaleArray(2) + 12
                  Case 66
                     Temp = ScaleArray(3) + 12
                  Case 68
                     Temp = ScaleArray(4) + 12
                  Case 70
                     Temp = ScaleArray(5) + 12
               End Select
               Call MidiOut(MIDICh , Temp , 0)
            End If

      End If
      QuNexusFlag = 0
   End If
Loop

Sub MIDIOut(Byval Ch As Byte , Byval Note As Byte , Byval Vel As Byte)
   Ch = &H8F + Ch
   SerialOut #1 , Ch
   SerialOut #1 , Note
   SerialOut #1 , Vel
End Sub

Sub MIDIPatch(byval Ch As Byte , Byval Patch As Byte)
   Ch = &HBF + Ch
   SerialOut #1 , Ch
   SerialOut #1 , Patch
End Sub

Sub MasterVolume(byval Vol As Byte)
   SerialOut #1 , 176
   SerialOut #1 , 7
   SerialOut #1 , Vol
End Sub

Sub AllNotesOff
   SerialOut #1 , &HB0
   SerialOut #1 , &H7B
   SerialOut #1 , &H00                   'All Notes Off
End Sub

Sub ProcessUntzButton
   ChordArray(1) = Root + Offset
   ScaleArray(1) = Root + Offset
   Select Case ChordType
      Case 0                            ' Major
         ChordArray(2) = ChordArray(1) + 7
         ChordArray(3) = ChordArray(1) + 16
         ChordArray(4) = ChordArray(1) + 24

         ScaleArray(2) = ScaleArray(1) + 2
         ScaleArray(3) = ScaleArray(1) + 4
         ScaleArray(4) = ScaleArray(1) + 7
         ScaleArray(5) = ScaleArray(1) + 9
      Case 1                            ' Minor
         ChordArray(2) = ChordArray(1) + 7
         ChordArray(3) = ChordArray(1) + 15
         ChordArray(4) = ChordArray(1) + 24

         ScaleArray(2) = ScaleArray(1) + 3
         ScaleArray(3) = ScaleArray(1) + 5
         ScaleArray(4) = ScaleArray(1) + 7
         ScaleArray(5) = ScaleArray(1) + 10
      Case 2                            ' Sus4
         ChordArray(2) = ChordArray(1) + 7
         ChordArray(3) = ChordArray(1) + 17
         ChordArray(4) = ChordArray(1) + 24

         ScaleArray(2) = ScaleArray(1) + 2
         ScaleArray(3) = ScaleArray(1) + 5
         ScaleArray(4) = ScaleArray(1) + 7
         ScaleArray(5) = ScaleArray(1) + 9
      Case 3                            ' Dom7
         ChordArray(2) = ChordArray(1) + 7
         ChordArray(3) = ChordArray(1) + 16
         ChordArray(4) = ChordArray(1) + 22

         ScaleArray(2) = ScaleArray(1) + 2
         ScaleArray(3) = ScaleArray(1) + 4
         ScaleArray(4) = ScaleArray(1) + 7
         ScaleArray(5) = ScaleArray(1) + 10
   End Select
End Sub

PCSerial_isr:
   SerialInbyte = Udr
   SerialFlag = 1
Return

QuNexus_ISR:
   QuNexusInbyte = UDR1
   Select Case QuNexusInbyte
      Case &H80 to &H9F                 'Note On / Off
         Status = QuNexusInbyte
         Data1 = &HFF
         Data2 = &HFF
      Case 0 To 127                     'Data
         If Status > 0 Then
            If Data1 = &HFF Then
               Data1 = QuNexusInbyte
            Else
               Data2 = QuNexusInbyte
               QuNexusFlag = 1
            End If
         End If
   End Select
Return

Untz_isr:
   UntzInbyte = Udr2
   UntzFlag = 1
Return