10  'PMSPLIT.BAS  "POOR MAN'S SPLIT",  BY LES PENNER,  12/21/86
15  ' Typed in by Jeff Tapia on 7-8-87 as read from
16  ' Electronic Musician Magazine (EM), July 1987
20  'PERFORMS KEYBOARD SPLIT OF A MIDI SYNTHESIZER USING MPU-401 INTERFACE
30  DEFINT A-Z
40  '#### NEXT EIGHT LINES ARE MPU-401 CODES
50  DataPort=&H330                         'MPU DATA PORT
60  StatPort=&H331                         'MPU STATUS PORT
70  CMDPort =&H331                         'MPU COMMAND PORT
80  DSRMask=&H80                           'DATA-SEND-READY MASK
90  DRRMask=&H40                           'DATA-RECEIVE-MASK
100 ACK     =&HFE                          'ACKNOWLEDGE
110 RST     =&HFF                          'MPU-401 Reset
120 DISM    =&H8B                          'DATA IN STOP MODE
130 WTSD    =&HD0                          'WANT TO SEND DATA
140 '#### NEXT TWO LINES ARE MIDI CODES
150 NoteOnOff=&H90 'MIDI NOTE ON/OFF CODE FOR CHANNEL 0
160 ChangePatch=&HC0                       'MIDI CHANGE PATCH
180 CLS : LOCATE 10,1
190 INPUT "Enter the key number for the split:",SplitKey
200 INPUT "Enter the patch number for the upper section:",HiPatch
210 Input "Enter the patch number for the lower section:",LoPatch
220 Print "Ready to play.  Press BREAK to terminate . . ."
230 Command=Rst : GoSub 520                'Send Reset Command
240 Command=Dism: Gosub 520                'Send Data-In-Stop Mode
250 Continue=1
260 While Continue=1: Gosub 450            'Get a byte from MPU-401
270   If InData=NoteOnOff then gosub 450   'If it is &H90 then get another
280   Note=InData:Gosub 450                'Get anouther byte from MPU-401
290   Velocity=InData                      'Velocity (volume)byte - not used
300   If Note>=SplitKey then NewRange=1 else NewRange=0 ' 1=upper, 0=lower
310   If ((NewRange=1)and(OldRange=0)) then Range=HiPatch
320     Gosub 650                          'Change from lower to upper patch
330   If ((NewRange=0)and(OldRange=1)) then Range=LoPatch
340     Gosub 650                          'Change from upper to lower patch
350   OldRange=NewRange
360 Wend
370 End
380 '#### Routine to send data to MPU-401
390 Status=&HFF
400 While not((Status and DRRMask)=0)      'Read Status Port until DRR is 0
410   Status=Inp(StatPort)
420 Wend
430 Out DataPort, OutData                  'Then send data to Data Port
440 Return
450 '#### Routine to send data to MPU-401
460 Status=&HFF
470 While not((Status and DSRMask)=0)       'Read Status Port until DSR is 0
480   Status=Inp(StatPort)
490 Wend
500 InData=Inp(DataPort)                   'Then read from Data Port
510 Return
520 '#### Routine to send a command to MPU-401
530 Status=&HFF : InData=&HFF : W=&HFF
540 While Not((Status and DRRMask)=0)      'Read Status port until DRR=0
550   Status=INP(StatPort)
560 Wend
570 Out CMDPort,Command                    'Then send the command to the CMDPort
580 While not(InData=Ack)                  'Start Looking for acknowledge from MPU-401
590   While Not((W and DSRMask)=0)         'Read Status Port Until DSR=0)
600     W=Inp(StatPort)                    'Read the Status Port byte
610   Wend
620   gosub 450                            'Get the data byte to see if it is Ack
630 Wend
640 Return
650 '#### Routine to switch to patches
660 Command=WTSD: Gosub 520                'Send Want-To-Send-Data command
670 OutData=ChangePatch: Gosub 380         'Send MIDI code to change patch
680 OutData=Range: Gosub 380               'Send data byte for new patch
690 Return
