home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 2 / crawlyvol2.bin / sound / psslib2 / psslib.lst < prev    next >
File List  |  1994-05-08  |  171KB  |  4,786 lines

  1. ' ***********************************************************************
  2. '       YAMAHA PATCH EDITOR/LIBRARIAN FOR THE PSS PORTASOUND SERIES     *
  3. '                                                                       *
  4. '                       PROGRAMMED IN GFA BASIC 3.07                    *
  5. '                       BY MICHAEL SILVERSTEIN                          *
  6. '                                                                       *
  7. '               VERSION: 2.00                                           *
  8. '               DATE: 07/20/92                                          *
  9. '                     FIXED CHECK_CONNECTION ROUTINE - PROGRAM RUNS     *
  10. '                     SLIGHTLY SLOWER DUE TO CLEARING MIDI BUFFER TO    *
  11. '                     PROPERLY HANDLE ACTIVE SENSING.                   *
  12. '                     ADDED MALLOC ROUTINES FOR BETTER VERSATILITY.     *
  13. '                     DELETED OLD C ROUTINES AND USED GFA ROUTINES TO   *
  14. '                     CHANGE SYSTEM MIDI BUFFER SIZE VIA XBIOS 14.      *
  15. '               DATE: 06/19/93                                          *
  16. '                     DELETED THE USAGE OF THE RESERVE COMMAND WHEN     *
  17. '                     PERFORMING AN EXEC TO THE LZH ARCHIVER FOR        *
  18. '                     COMPATABILITY WITH CODEHEAD'S MIDI SPY.           *
  19. '                     NOW USING THE COMPILER $M COMMAND!                *
  20. '                     ADDED CHANNELIZATION WHEN SENDING PROGRAM CHANGES *
  21. '                     AND/OR THE PATCHES TO THE SYNTH (I.E. BANK 1 IS   *
  22. '                     CHANNEL 1, BANK 2 IS CHANNEL 2, ETC.)             *
  23. '                     TURNED MOUSE OFF WHEN DOING A VERBOSE LIST OF THE *
  24. '                     SYSTEM MIDI ARCHIVE.                              *
  25. '               DATE: 07/21/93                                          *
  26. '                     INCREASED COMPILER ($M) DIRECTIVE SINCE RECEIVING *
  27. '                     MIDI CAUSED HELP/DIALOG BOXES TO CAUSE ERRORS.    *
  28. '               DATE: 01/28/94                                          *
  29. '                     COMPILED WITH INTERRUPTS (I+) SET FOR LESS CHANCE *
  30. '                     OF RECEIVE CHECKSUM ERRORS WHEN MANY TSR'S ARE    *
  31. '                     LOADED IN AUTO FOLDER.  ALSO, FIXED A BUG WHICH   *
  32. '                     CAUSED THE PROGRAM TO HANG WHEN ATTEMPTING TO     *
  33. '                     QUIT.
  34. '               DATE: 04/24/94                                          *
  35. '                     ADDED EXPORTING OF PATCH WHEN SAVING. A FILE WILL *
  36. '                     BE CREATED WITH A .SYX EXTENSION. THIS WILL       *
  37. '                     INCLUDE THE SYSEX HEADER/TAILOR BYTES TO BE USED  *
  38. '                     WITH OTHER MIDI PROGRAMS, SEQUENCERS.             *
  39. '                                                                       *
  40. '                     ADDED IMPORTING/EXPORTING CUSTOM DRUMMER INFO     *
  41. '                     (THE LAST SYSEX MESSAGE) BY UPDATING THE SYSTEM   *
  42. '                     MIDI BUFFER TO 13,800 BYTES.  THESE FUNCTIONS WILL*
  43. '                     ALSO USE THE FILE SELECTOR TO LOAD OR SAVE A      *
  44. '                     DRUMMER FILE WITH A .SYX EXTENSION.  THE ONLINE   *
  45. '                     HELP AND KEYBOARD EQUIVALENTS WERE MODIFIED TO    *
  46. '                     REFLECT THESE CHANGES. NOTE THAT IMPORTING WORKS  *
  47. '                     FOR PATCHES AS WELL AS THE CUSTOM DRUMMER.        *
  48. '                                                                       *
  49. '                     RESTORING THE ORIGINAL MIDI BUFFER IS NOW ITS OWN *
  50. '                     ROUTINE AND IS CALLED AFTER A SUCCESSFUL RECEPTION*
  51. '                     OF MIDI DATA.  THIS WAS DONE SINCE THE MIDI BUFFER*
  52. '                     WAS NOT GETTING RESTORED CORRECTLY WHEN QUITTING  *
  53. '                     THE PROGRAM DUE TO TOO MANY CHANGES WITH THE      *
  54. '                     SYSTEM BUFFER.                                    *
  55. '                                                                       *
  56. '                     NOW USING THE EVNT_TIMER (AES) LIBRARY ROUTINE    *
  57. '                     WHEN CHECKING FOR ACTIVE SENSING.  THIS WAS FOUND *
  58. '                     TO WORK MUCH BETTER SINCE THE PAUSE COMMAND WAS   *
  59. '                     CAUSING TOO MUCH DELAY WITH GFA MENU SELECTIONS.  *
  60. '                                                                       *
  61. '                     A NEW AUDITION MODE WAS IMPLEMENTED WHICH WILL    *
  62. '                     PLAY 3 MIDI NOTES WHEN ISSUING A 'SEND' COMMAND   *
  63. '                     TO THE YAMAHA.  THIS MODE MAY BE TOGGLED AND AN   *
  64. '                     INPUT DIALOG BOX ALLOWS YOU TO SPECIFY THE TOTAL  *
  65. '                     TIME (IN SECONDS)TO AUDITION EACH NOTE, WITH      *
  66. '                     VALUES OF 3, 9, 21 AND 30 SECONDS AS CHOICE       *
  67. '                     OPTIONS. A KEY EQUIVALENT FEATUE IS ALSO          *
  68. '                     SUPPORTED AND A POPUP STATUS DISPLAY WILL INDICATE*
  69. '                     WHEN EACH NOTE (LOW, MEDIUM, HIGH) NOTE IS SENT.  *
  70. '                                                                       *
  71. '                     FINALLY FIXED THE 'FILE DOESN'T EXIST' BUG WHEN   *
  72. '                     USING THE FILESELECT CALL TO GET A PATCH NAME OR  *
  73. '                     .SYX FILE.  IF THE NAME DOESN'T EXIST, THE ROUTINE*
  74. '                     WILL KEEP LOOPING UNTIL A VALID NAME IS ENTERED   *
  75. '                     OR THE USER CAN BAIL OUT VIA THE CANCEL BUTTON.   *
  76. '                                                                       *
  77. '                     UPDATED CERTAIN SCREENS SUPPORTING HI REZ MONO-   *
  78. '                     CHROME.                                           *
  79. '                                                                       *
  80. '                     MADE SURE THAT A .SYX DOESN'T ACCIDENTALLY GET    *
  81. '                     DELETED IF USER SELECTS TO LOAD A PATCH (FROM     *
  82. '                     ARCHIVE).  AN ERROR MESSAGE IS DISPLAYED TO USE   *
  83. '                     IMPORT FOR THIS FEATURE.                          *
  84. ' ***********************************************************************
  85. '
  86. ' ***********************************************************************
  87. ' CHECK REZ, INITIALIZE GEM MENU, MOUSE POINTER, ETC.
  88. ' ***********************************************************************
  89. '
  90. rez=XBIOS(4)
  91. IF rez=0 THEN
  92.   ALERT 3,"Sorry, this program does not|run in low resolution",1,"OK",b
  93.   END
  94. ENDIF
  95. GRAPHMODE 1                             ! mode for text graphics
  96. DEFMOUSE 3                              ! pointing hand mouse cursor
  97. init_buffer                             ! initialize system MIDI buffer array
  98. init_parameters                         ! initialize all Patch parameters
  99. midi.buff.adr=0                         ! initialize system midi buffer address
  100. auditon_flag=FALSE                      ! initialize audition flag to OFF
  101. midi_delay=0                            ! initialize note on delay value to OFF
  102. $m200000                                ! reserve 200K for PSSLIB and LHA
  103. no_connection=TRUE                      ! initialize MIDI connection flag to ON
  104. DIM m$(100)                             ! setup for GEM menu
  105. m$(0)="Desk "
  106. m$(1)=" About Program "
  107. m$(2)="-----------------------"
  108. m$(3)="1"
  109. m$(4)="2"
  110. m$(5)="3"
  111. m$(6)="4"
  112. m$(7)="5"
  113. m$(8)="6"
  114. m$(9)=""
  115. m$(10)="File"
  116. m$(11)=" Load Patch "
  117. m$(12)=" Save Patch "
  118. m$(13)=" Delete Patch "
  119. m$(14)=" Build Patch "
  120. m$(15)=" Verbose Directory"
  121. m$(16)=" Quit "
  122. m$(17)=""
  123. m$(18)="Buffer"
  124. m$(19)=" View in Bytes "
  125. m$(20)=""
  126. m$(21)="MIDI"
  127. m$(22)=" Send Bank 1 "
  128. m$(23)=" Send Bank 2 "
  129. m$(24)=" Send Bank 3 "
  130. m$(25)=" Send Bank 4 "
  131. m$(26)=" Send Bank 5 "
  132. s$="modulation"
  133. m$(27)="----------------"
  134. m$(28)=" Receive Bank 1 "
  135. m$(29)=" Receive Bank 2 "
  136. m$(30)=" Receive Bank 3 "
  137. m$(31)=" Receive Bank 4 "
  138. m$(32)=" Receive Bank 5 "
  139. m$(33)="----------------"
  140. m$(34)=" Import .SYX "
  141. m$(35)=" Export Drum "
  142. m$(36)="----------------"
  143. m$(37)="  Audition "
  144. m$(38)=""
  145. m$(39)="Modulation"
  146. m$(40)=" Leveling "
  147. m$(41)=" AM/FM "
  148. m$(42)=""
  149. m$(43)="Modulator"
  150. m$(44)=" Define Waveform "
  151. m$(45)=" Tuning "
  152. m$(46)=" Frequency Multiplier"
  153. t$="midilation"
  154. m$(47)=" LKS/RKS "
  155. m$(48)=" Enveloping "
  156. m$(49)=""
  157. m$(50)="Carrier"
  158. m$(51)=" Define Waveform "
  159. m$(52)=" Tuning "
  160. m$(53)=" Frequency Multiplier"
  161. m$(54)=" LKS/RKS "
  162. m$(55)=" Enveloping "
  163. m$(56)=""
  164. m$(57)="Help "
  165. m$(58)=" General"
  166. m$(59)=" File "
  167. m$(60)=" Buffer "
  168. m$(61)=" MIDI "
  169. m$(62)=" Modulation"
  170. m$(63)=" Modulator/Carrier"
  171. m$(64)=" Key Equivalents"
  172. MENU m$()                               ! Display Menu
  173. IF s$<>t$
  174.   demo_mode=TRUE
  175. ELSE
  176.   demo_mode=FALSE
  177. ENDIF
  178. about_editor_librarian
  179. check_viewmode
  180. ' ***********************************************************************
  181. ' TURN OFF SAVE,MIDI EDIT PARAMETERS
  182. ' ***********************************************************************
  183. MENU 12,2
  184. FOR i=39 TO 55
  185.   MENU i,2
  186. NEXT i
  187. ' ***********************************************************************
  188. ' XFER PROGRAM CONTROL TO GEM MENU
  189. ' ***********************************************************************
  190. ON MENU GOSUB main
  191. DO
  192.   check_connection                      !Check for MIDI connection
  193.   IF audition_flag
  194.     MENU 37,1                           !Toggle Audition Mode (checked)
  195.   ELSE
  196.     MENU 37,0                           !Toggle Audition Mode (unchecked)
  197.   ENDIF
  198.   ON MENU KEY GOSUB key_value           !Check Key Equivalents
  199.   ON MENU
  200.   SHOWM                                 !Show mouse pointer
  201. LOOP
  202. ' ***********************************************************************
  203. ' MAIN GEM MENU ROUTINE - CALL ROUTINES BASED ON PULL DOWN MENUS
  204. ' ***********************************************************************
  205. PROCEDURE main
  206.   button=MENU(0)
  207.   MENU OFF
  208.   SELECT button
  209.   CASE 1
  210.     about_editor_librarian
  211.   CASE 16
  212.     ' ***********************************************************************
  213.     ' Quit Selection
  214.     ' ***********************************************************************
  215.     ALERT 2,"Are you Sure?",1,"yes|no",b
  216.     SELECT b
  217.     CASE 1
  218.       END
  219.     CASE 2
  220.     ENDSELECT
  221.   CASE 14
  222.     ' ***********************************************************************
  223.     ' Build Selection
  224.     ' ***********************************************************************
  225.     init_buffer                         ! reinitialize system MIDI buffer
  226.     check_viewmode
  227.   CASE 19
  228.     ' ***********************************************************************
  229.     ' View Selection
  230.     ' ***********************************************************************
  231.     flag=NOT (flag)                     ! complement viewmode flag
  232.     IF m$(19)=" View in Bytes " THEN    ! change view mode according to flag
  233.       m$(19)=" View Parameters "
  234.       view_bytes
  235.     ELSE
  236.       IF m$(19)=" View Parameters " THEN
  237.         m$(19)=" View in Bytes "
  238.         view_parameters
  239.       ENDIF
  240.     ENDIF
  241.   CASE 45
  242.     ' ***********************************************************************
  243.     ' Tune Modulator Selection(Fine/Course Detune)
  244.     ' ***********************************************************************
  245.     tune_modulator(cdt_mod,d1r_mod,am_en_mod)
  246.     PAUSE 10
  247.     check_viewmode
  248.   CASE 52
  249.     ' ***********************************************************************
  250.     ' Tune Carrier Selection(Fine/Course Detune)
  251.     ' ***********************************************************************
  252.     tune_carrier(cdt_car,d1r_car,am_en_car)
  253.     PAUSE 10
  254.     check_viewmode
  255.   CASE 46
  256.     ' ***********************************************************************
  257.     ' Frequency Multiply Modulator Selection
  258.     ' ***********************************************************************
  259.     freq_modulator            ! Frequency Multiply Modulator
  260.     PAUSE 10
  261.     check_viewmode
  262.   CASE 53
  263.     ' ***********************************************************************
  264.     ' Frequency Multiply Carrier Selection
  265.     ' ***********************************************************************
  266.     freq_carrier              ! Frequency Multiply Carrier
  267.     PAUSE 10
  268.     check_viewmode
  269.   CASE 40
  270.     ' ***********************************************************************
  271.     ' Leveling Selection
  272.     ' ***********************************************************************
  273.     leveling                  ! Do leveling parameters
  274.     PAUSE 10
  275.     check_viewmode
  276.   CASE 47
  277.     ' ***********************************************************************
  278.     ' Level/Rate Key Scale Modulator Selection
  279.     ' ***********************************************************************
  280.     lks_rks_modulator(rks_mod,atk_mod)
  281.     check_viewmode
  282.   CASE 54
  283.     ' ***********************************************************************
  284.     ' Level/Rate Key Scale Carrier Selection
  285.     ' ***********************************************************************
  286.     lks_rks_carrier(rks_car,atk_car)
  287.     PAUSE 10
  288.     check_viewmode
  289.     ' ***********************************************************************
  290.     ' Enveloping for Modulator Selection
  291.     ' ***********************************************************************
  292.   CASE 48
  293.     envelope_mod(rks_mod,atk_mod,d1r_mod,am_en_mod,cdt_mod,d2r_mod,wavform_mod)
  294.     PAUSE 10
  295.     check_viewmode
  296.   CASE 55
  297.     ' ***********************************************************************
  298.     ' Enveloping for Carrier Selection
  299.     ' ***********************************************************************
  300.     envelope_car(rks_car,atk_car,d1r_car,am_en_car,cdt_car,d2r_car,wavform_car)
  301.     PAUSE 10
  302.     check_viewmode
  303.   CASE 44
  304.     ' ***********************************************************************
  305.     ' Define Basic Waveform Shape for Modulator Selection
  306.     ' ***********************************************************************
  307.     wave_mod(wavform_mod,d2r_mod)
  308.     PAUSE 10
  309.     check_viewmode
  310.   CASE 51
  311.     ' ***********************************************************************
  312.     ' Define Basic Waveform Shape for Carrier Selection
  313.     ' ***********************************************************************
  314.     wave_car(wavform_car,d2r_car)
  315.     PAUSE 10
  316.     check_viewmode
  317.   CASE 41
  318.     ' ***********************************************************************
  319.     ' AM/FM Parameters Selection
  320.     ' ***********************************************************************
  321.     am_fm
  322.     PAUSE 10
  323.     check_viewmode
  324.   CASE 22
  325.     ' ***********************************************************************
  326.     ' Send Midi Patch Buffer to Bank 1 Selection
  327.     ' ***********************************************************************
  328.     send_1
  329.     '
  330.   CASE 23
  331.     ' ***********************************************************************
  332.     ' Send Midi Patch Buffer to Bank 2 Selection
  333.     ' ***********************************************************************
  334.     send_2
  335.     '
  336.   CASE 24
  337.     ' ***********************************************************************
  338.     ' Send Midi Patch Buffer to Bank 3 Selection
  339.     ' ***********************************************************************
  340.     send_3
  341.     '
  342.   CASE 25
  343.     ' ***********************************************************************
  344.     ' Send Midi Patch Buffer to Bank 4 Selection
  345.     ' ***********************************************************************
  346.     send_4
  347.     '
  348.   CASE 26
  349.     ' ***********************************************************************
  350.     ' Send Midi Patch Buffer to Bank 5 Selection
  351.     ' ***********************************************************************
  352.     send_5
  353.     '
  354.   CASE 28
  355.     ' ***********************************************************************
  356.     ' Receive from Banks 1 thru 5 to MIDI Patch Buffer Selections
  357.     ' ***********************************************************************
  358.     bank=1
  359.     midi_ready_prompt(bank)          ! receive from bank 1 to buffer
  360.   CASE 29
  361.     bank=2
  362.     midi_ready_prompt(bank)          ! receive from bank 2 to buffer
  363.   CASE 30
  364.     bank=3
  365.     midi_ready_prompt(bank)          ! receive from bank 3 to buffer
  366.   CASE 31
  367.     bank=4
  368.     midi_ready_prompt(bank)          ! receive from bank 4 to buffer
  369.   CASE 32
  370.     bank=5
  371.     midi_ready_prompt(bank)          ! receive from bank 5 to buffer
  372.   CASE 34
  373.     ' ***********************************************************************
  374.     ' Import Custom Drummer or Patch .SYX SYSEX files
  375.     ' ***********************************************************************
  376.     send_drummer
  377.     check_viewmode
  378.   CASE 35
  379.     ' ***********************************************************************
  380.     ' Export Yamaha Custom Drummer to .SYX SYSEX file
  381.     ' ***********************************************************************
  382.     receive_drummer
  383.     check_viewmode
  384.   CASE 37
  385.     ' ***********************************************************************
  386.     ' Configure Audition Mode when sending out MIDI patch data
  387.     ' ***********************************************************************
  388.     IF audition_flag THEN
  389.       MENU 37,0                                 !Toggle Audition Menu check off
  390.       audition_flag=FALSE                       !Clear Audition Flag
  391.       midi_delay=0
  392.     ELSE
  393.       MENU 37,1                                 !Toggle Audition Menu check on
  394.       audition_flag=TRUE                        !Set Audition Flag
  395.       delay_note_on(midi_delay)                 !Get note on delay value
  396.     ENDIF
  397.   CASE 12
  398.     ' ***********************************************************************
  399.     ' Save Patch to Disk Archive Selection
  400.     ' ***********************************************************************
  401.     IF demo_mode
  402.       ALERT 1,"Sorry, this is a DEMO!|You cannot save your work.",1,"Will pay!",b
  403.     ELSE
  404.       patch_save
  405.       check_viewmode
  406.     ENDIF
  407.   CASE 11
  408.     ' ***********************************************************************
  409.     ' Load Patch from Disk Archive Selection
  410.     ' ***********************************************************************
  411.     patch_load
  412.     check_viewmode
  413.   CASE 13
  414.     ' ***********************************************************************
  415.     ' Delete Patch from Disk Archive Selection
  416.     ' ***********************************************************************
  417.     patch_delete
  418.     check_viewmode
  419.   CASE 15
  420.     ' ***********************************************************************
  421.     ' Verbose directory from Disk Archive Selection
  422.     ' ***********************************************************************
  423.     verbose
  424.     check_viewmode
  425.   CASE 58
  426.     about_general
  427.   CASE 59
  428.     about_file
  429.   CASE 60
  430.     about_buffer
  431.   CASE 61
  432.     about_midi
  433.   CASE 62
  434.     about_modulation
  435.   CASE 63
  436.     about_mod_car
  437.   CASE 64
  438.     about_key_equiv
  439.   ENDSELECT
  440.   '
  441.   ' ***********************************************************************
  442.   ' TURN OFF/ON APPROPRIATE SELECTIONS BASED ON THE MAIN DROP-DOWN MENU
  443.   ' SELECTIONS.
  444.   ' ***********************************************************************
  445.   SELECT button
  446.   CASE 11 TO 14                      ! turn off 'save' when 'load' 'save'
  447.     MENU 12,2                        ! 'build','delete
  448.   ENDSELECT
  449.   SELECT button
  450.   CASE 39 TO 55                      ! turn off 'load' 'delete' and 'receive'
  451.     MENU 11,2                        !  when editing all parameters
  452.     MENU 13,2
  453.     FOR i=28 TO 32                   ! turn off Receive MIDI banks
  454.       MENU i,2
  455.     NEXT i
  456.     MENU 35,2                        !turn off Receive Custom Drummer
  457.   ENDSELECT
  458.   SELECT button
  459.   CASE 22 TO 26                      ! turn on 'load 'delete' and 'receive'
  460.     MENU 11,3                        ! after sending to Yamaha
  461.     MENU 13,3
  462.     FOR i=28 TO 32
  463.       MENU i,3
  464.     NEXT i
  465.     MENU 35,3
  466.   ENDSELECT
  467.   SELECT button
  468.   CASE 28 TO 32                      ! turn off 'load 'delete'and 'build' after
  469.     MENU 11,2                        ! receiving from Yamaha
  470.     MENU 13,2
  471.     MENU 14,2
  472.   ENDSELECT
  473. RETURN
  474. '
  475. ' ***********************************************************************
  476. ' CHECK FOR YAMAHA KEYBOARD INSTRUMENT
  477. ' ***********************************************************************
  478. '
  479. PROCEDURE check_connection
  480.   '
  481.   buffer$=INPMID$                       ! clear midi buffer
  482.   timer=EVNT_TIMER(300)                 ! delay 300ms for active sense
  483.   IF INP?(3)=-1 THEN                    ! turn on 'send' and 'receive' when
  484.     active_sense$=HEX$(INP(3))
  485.     IF active_sense$="FE" THEN
  486.       FOR i=22 TO 37                    ! Yamaha is turned on or plugged in
  487.         MENU i,3
  488.       NEXT i
  489.       no_connection=FALSE               ! clear flag
  490.     ENDIF
  491.   ELSE
  492.     FOR i=22 TO 37                      ! Yamaha is not turned on or plugged in
  493.       MENU i,2
  494.     NEXT i
  495.     no_connection=TRUE                  ! set flag
  496.     audition_flag=FALSE                 ! clear flag
  497.   ENDIF
  498.   '
  499. RETURN
  500. '
  501. ' ***********************************************************************
  502. ' KEY-VALUE SIMULATES THE GEM DROP DOWN MENU WITH KEYBOARD EQUIVALENT KEYS.
  503. ' THIS IS ACCOMPLISHED VIA OBTAINING SCAN CODES,ASCII CODES (MENU(14)
  504. ' AND ALT/CONTROL CODES (MENU (13) OF AN INPUT KEY AND PERFORMING A MOD
  505. ' 256 TO GET THE ASCII CODE AND A DIV 256 TO GET THE SCAN CODE.
  506. ' ***********************************************************************
  507. '
  508. PROCEDURE key_value
  509.   '
  510.   x=MENU(13)
  511.   y=MENU(14)
  512.   z=256
  513.   IF (y MOD z=49) AND (y DIV z=109)     !Numeric 1
  514.     SELECT no_connection
  515.     CASE -1
  516.       ALERT 1,"No MIDI connection!|Check power or MIDI chords.",1,"OK",b
  517.       GOTO end_key_value
  518.     CASE 0
  519.       OUT 3,&HC0
  520.       OUT 3,100
  521.       CLS
  522.       MENU m$()
  523.       PRINT AT(25,15);"Sent Program Change to Bank 1.";
  524.     ENDSELECT
  525.   ENDIF
  526.   IF (y MOD z=50) AND (y DIV z=110)     !Numeric 2
  527.     SELECT no_connection
  528.     CASE -1
  529.       ALERT 1,"No MIDI connection!|Check power or MIDI chords.",1,"OK",b
  530.       GOTO end_key_value
  531.     CASE 0
  532.       OUT 3,&HC0
  533.       OUT 3,101
  534.       CLS
  535.       MENU m$()
  536.       PRINT AT(25,15);"Sent Program Change to Bank 2.";
  537.     ENDSELECT
  538.   ENDIF
  539.   IF (y MOD z=51) AND (y DIV z=111)     !Numeric 3
  540.     SELECT no_connection
  541.     CASE -1
  542.       ALERT 1,"No MIDI connection!|Check power or MIDI chords.",1,"OK",b
  543.       GOTO end_key_value
  544.     CASE 0
  545.       OUT 3,&HC0
  546.       OUT 3,102
  547.       CLS
  548.       MENU m$()
  549.       PRINT AT(25,15);"Sent Program Change to Bank 3.";
  550.     ENDSELECT
  551.   ENDIF
  552.   IF (y MOD z=52) AND (y DIV z=106)     !Numeric 4
  553.     SELECT no_connection
  554.     CASE -1
  555.       ALERT 1,"No MIDI connection!|Check power or MIDI chords.",1,"OK",b
  556.       GOTO end_key_value
  557.     CASE 0
  558.       OUT 3,&HC0
  559.       OUT 3,103
  560.       CLS
  561.       MENU m$()
  562.       PRINT AT(25,15);"Sent Program Change to Bank 4.";
  563.     ENDSELECT
  564.   ENDIF
  565.   IF (y MOD z=53) AND (y DIV z=107)     !Numeric 5
  566.     SELECT no_connection
  567.     CASE -1
  568.       ALERT 1,"No MIDI connection!|Check power or MIDI chords.",1,"OK",b
  569.       GOTO end_key_value
  570.     CASE 0
  571.       OUT 3,&HC0
  572.       OUT 3,104
  573.       CLS
  574.       MENU m$()
  575.       PRINT AT(25,15);"Sent Program Change to Bank 5.";
  576.     ENDSELECT
  577.   ENDIF
  578.   IF (x=0) AND (y MOD z=0) AND (y DIV z=59) !F1
  579.     SELECT no_connection
  580.     CASE -1
  581.       ALERT 1,"No MIDI connection!|Check power or MIDI chords.",1,"OK",b
  582.       GOTO end_key_value
  583.     CASE 0
  584.       send_1
  585.       CLS
  586.       MENU m$()
  587.       PRINT AT(25,15);"Sent buffer to Bank 1.                  ";
  588.     ENDSELECT
  589.   ENDIF
  590.   IF (x=0) AND (y MOD z=0) AND (y DIV z=60) !F2
  591.     SELECT no_connection
  592.     CASE -1
  593.       ALERT 1,"No MIDI connection!|Check power or MIDI chords.",1,"OK",b
  594.       GOTO end_key_value
  595.     CASE 0
  596.       send_2
  597.       CLS
  598.       MENU m$()
  599.       PRINT AT(25,15);"Sent buffer to Bank 2.                  ";
  600.     ENDSELECT
  601.   ENDIF
  602.   IF (x=0) AND (y MOD z=0) AND (y DIV z=61) !F3
  603.     SELECT no_connection
  604.     CASE -1
  605.       ALERT 1,"No MIDI connection!|Check power or MIDI chords.",1,"OK",b
  606.       GOTO end_key_value
  607.     CASE 0
  608.       send_3
  609.       CLS
  610.       MENU m$()
  611.       PRINT AT(25,15);"Sent buffer to Bank 3.                  ";
  612.     ENDSELECT
  613.   ENDIF
  614.   IF (x=0) AND (y MOD z=0) AND (y DIV z=62) !F4
  615.     SELECT no_connection
  616.     CASE -1
  617.       ALERT 1,"No MIDI connection!|Check power or MIDI chords.",1,"OK",b
  618.       GOTO end_key_value
  619.     CASE 0
  620.       send_4
  621.       CLS
  622.       MENU m$()
  623.       PRINT AT(25,15);"Sent buffer to Bank 4.                  ";
  624.     ENDSELECT
  625.   ENDIF
  626.   IF (x=0) AND (y MOD z=0) AND (y DIV z=63) !F5
  627.     SELECT no_connection
  628.     CASE -1
  629.       ALERT 1,"No MIDI connection!|Check power or MIDI chords.",1,"OK",b
  630.       GOTO end_key_value
  631.     CASE 0
  632.       send_5
  633.       CLS
  634.       MENU m$()
  635.       PRINT AT(25,15);"Sent buffer to Bank 5.                  ";
  636.     ENDSELECT
  637.   ENDIF
  638.   IF (x=0) AND (y MOD z=0) AND (y DIV z=64) !F6
  639.     SELECT no_connection
  640.     CASE -1
  641.       ALERT 1,"No MIDI connection!|Check power or MIDI chords.",1,"OK",b
  642.       GOTO end_key_value
  643.     CASE 0
  644.       send_drummer
  645.       check_viewmode
  646.     ENDSELECT
  647.   ENDIF
  648.   IF (x=8) AND (y MOD z=0) AND (y DIV z=59) !Alt-F1
  649.     SELECT no_connection
  650.     CASE -1
  651.       ALERT 1,"No MIDI connection!|Check power or MIDI chords.",1,"OK",b
  652.       GOTO end_key_value
  653.     CASE 0
  654.       bank=1
  655.       midi_ready_prompt(bank)          !Receive from bank 1
  656.       MENU 11,2                        ! receiving from Yamaha
  657.       MENU 13,2
  658.       MENU 14,2
  659.     ENDSELECT
  660.   ENDIF
  661.   IF (x=8) AND (y MOD z=0) AND (y DIV z=60) !Alt-F2
  662.     SELECT no_connection
  663.     CASE -1
  664.       ALERT 1,"No MIDI connection!|Check power or MIDI chords.",1,"OK",b
  665.       GOTO end_key_value
  666.     CASE 0
  667.       bank=2
  668.       midi_ready_prompt(bank)          !Receive from bank 2
  669.       MENU 11,2
  670.       MENU 13,2
  671.       MENU 14,2
  672.     ENDSELECT
  673.   ENDIF
  674.   IF (x=8) AND (y MOD z=0) AND (y DIV z=61) !Alt-F3
  675.     SELECT no_connection
  676.     CASE -1
  677.       ALERT 1,"No MIDI connection!|Check power or MIDI chords.",1,"OK",b
  678.       GOTO end_key_value
  679.     CASE 0
  680.       bank=3
  681.       midi_ready_prompt(bank)              !Receive from bank 3
  682.       MENU 11,2
  683.       MENU 13,2
  684.       MENU 14,2
  685.     ENDSELECT
  686.   ENDIF
  687.   IF (x=8) AND (y MOD z=0) AND (y DIV z=62) !Alt-F4
  688.     SELECT no_connection
  689.     CASE -1
  690.       ALERT 1,"No MIDI connection!|Check power or MIDI chords.",1,"OK",b
  691.       GOTO end_key_value
  692.     CASE 0
  693.       bank=4
  694.       midi_ready_prompt(bank)              !Receive from bank 4
  695.       MENU 11,2
  696.       MENU 13,2
  697.       MENU 14,2
  698.     ENDSELECT
  699.   ENDIF
  700.   IF (x=8) AND (y MOD z=0) AND (y DIV z=63) !Alt-F5
  701.     SELECT no_connection
  702.     CASE -1
  703.       ALERT 1,"No MIDI connection!|Check power or MIDI chords.",1,"OK",b
  704.       GOTO end_key_value
  705.     CASE 0
  706.       bank=5
  707.       midi_ready_prompt(bank)              !Receive from bank 5
  708.       MENU 11,2
  709.       MENU 13,2
  710.       MENU 14,2
  711.     ENDSELECT
  712.   ENDIF
  713.   IF (x=8) AND (y MOD z=0) AND (y DIV z=64) !Alt-F6
  714.     SELECT no_connection
  715.     CASE -1
  716.       ALERT 1,"No MIDI connection!|Check power or MIDI chords.",1,"OK",b
  717.       GOTO end_key_value
  718.     CASE 0
  719.       receive_drummer
  720.       CLS
  721.       MENU m$()
  722.       check_viewmode
  723.     ENDSELECT
  724.   ENDIF
  725.   IF (x=0) AND ((y MOD z=118) OR (y MOD z=86)) AND (y DIV z=47) !'v or V' key
  726.     flag=NOT (flag)                     ! complement viewmode flag
  727.     IF m$(19)=" View in Bytes " THEN    ! change view mode according to flag
  728.       m$(19)=" View Parameters "
  729.       view_bytes
  730.     ELSE
  731.       IF m$(19)=" View Parameters " THEN
  732.         m$(19)=" View in Bytes "
  733.         view_parameters
  734.       ENDIF
  735.     ENDIF
  736.   ENDIF
  737.   IF (x=4) AND (y MOD z=22) AND (y DIV z=47)  !'CNTL-v' key
  738.     ALERT 2,"Verbose Directory?",1,"yes|no",b
  739.     SELECT b
  740.     CASE 1
  741.       verbose
  742.       check_viewmode
  743.     CASE 2
  744.     ENDSELECT
  745.   ENDIF
  746.   IF ((y MOD z=108) OR (y MOD z=76)) AND (y DIV z=38)      !'l or L' key
  747.     ALERT 2,"Load Patch?",1,"yes|no",b
  748.     SELECT b
  749.     CASE 1
  750.       patch_load
  751.       check_viewmode
  752.     CASE 2
  753.     ENDSELECT
  754.     MENU 12,2
  755.   ENDIF
  756.   IF ((y MOD z=115) OR (y MOD z=83)) AND (y DIV z=31)      !'s or S' key
  757.     ALERT 2,"Save Patch?",1,"yes|no",b
  758.     SELECT b
  759.     CASE 1
  760.       IF demo_mode
  761.         ALERT 1,"Sorry, this is a DEMO!|You cannot save your work.",1,"Will pay!",b
  762.       ELSE
  763.         patch_save
  764.         check_viewmode
  765.       ENDIF
  766.     CASE 2
  767.     ENDSELECT
  768.     MENU 12,2
  769.   ENDIF
  770.   IF ((y MOD z=97) OR (y MOD z=65)) AND (y DIV z=30)      !'a or A' key
  771.     SELECT no_connection
  772.     CASE -1
  773.       ALERT 1,"No MIDI connection!|Check power or MIDI chords.",1,"OK",b
  774.       audition_flag=FALSE
  775.       midi_delay=0
  776.       GOTO end_key_value
  777.     CASE 0
  778.       IF audition_flag=FALSE
  779.         ALERT 2,"Audition Mode checked?",1,"yes|no",b
  780.         SELECT b
  781.         CASE 1
  782.           MENU 37,1                                 !Toggle Audition Menu check on
  783.           audition_flag=TRUE                        !Set Audition Flag
  784.           CLS
  785.           HIDEM
  786.           PRINT AT(20,9);"Enter delay value selection:"
  787.           PRINT AT(20,11);"<numeric key 1> 3 seconds"
  788.           PRINT AT(20,12);"<numeric key 2> 9 seconds"
  789.           PRINT AT(20,13);"<numeric key 3> 21 seconds"
  790.           PRINT AT(20,14);"<numeric key 4> 30 seconds"
  791.           DO
  792.             KEYGET key
  793.             EXIT IF key=7143473 OR key=7209010 OR key=7274547 OR key=6946868
  794.           LOOP
  795.           SELECT key
  796.           CASE 7143473
  797.             midi_delay=1
  798.           CASE 7209010
  799.             midi_delay=2
  800.           CASE 7274547
  801.             midi_delay=3
  802.           CASE 6946868
  803.             midi_delay=4
  804.           ENDSELECT
  805.           CLS
  806.           MENU m$()
  807.           PRINT AT(9,9);"Audition delay time will be";
  808.           SELECT midi_delay
  809.           CASE 1
  810.             PRINT " 3 seconds (1 second between notes)"
  811.           CASE 2
  812.             PRINT " 9 seconds (3 seconds between notes)"
  813.           CASE 3
  814.             PRINT " 21 seconds (7 seconds between notes)"
  815.           CASE 4
  816.             PRINT " 30 seconds (10 seconds between notes)"
  817.           ENDSELECT
  818.         CASE 2
  819.         ENDSELECT
  820.       ELSE
  821.         ALERT 2,"Audition Mode unchecked?",1,"yes|no",b
  822.         SELECT b
  823.         CASE 1
  824.           MENU 37,1                                 !Toggle Audition Menu check on
  825.           audition_flag=FALSE                        !Set Audition Flag
  826.           midi_delay=0
  827.         CASE 2
  828.         ENDSELECT
  829.       ENDIF
  830.       MENU 12,2
  831.     ENDSELECT
  832.   ENDIF
  833.   IF ((y MOD z=98) OR (y MOD z=66)) AND (y DIV z=48)      !'b or B' key
  834.     ALERT 2,"Build Patch?",1,"yes|no",b
  835.     SELECT b
  836.     CASE 1
  837.       init_buffer
  838.       check_viewmode
  839.     CASE 2
  840.     ENDSELECT
  841.     MENU 12,2
  842.   ENDIF
  843.   IF ((y MOD z=100) OR (y MOD z=68)) AND (y DIV z=32)     !'d or D' key
  844.     ALERT 2,"Delete Patch?",1,"yes|no",b
  845.     SELECT b
  846.     CASE 1
  847.       patch_delete
  848.       check_viewmode
  849.     CASE 2
  850.     ENDSELECT
  851.     MENU 12,2
  852.   ENDIF
  853.   IF ((y MOD z=113) OR (y MOD z=81)) AND (y DIV z=16)     !'q or Q' key
  854.     ALERT 2,"Are you Sure?",1,"yes|no",b
  855.     SELECT b
  856.     CASE 1
  857.       END
  858.     CASE 2
  859.     ENDSELECT
  860.   ENDIF
  861.   IF (x=0) AND (y MOD z=0) AND (y DIV z=98) !'HELP' key
  862.     about_general
  863.   ENDIF
  864.   IF (x=4) AND (y MOD z=0) AND (y DIV z=98) !'CNTL-HELP' key
  865.     about_file
  866.   ENDIF
  867.   IF (x=2) AND (y MOD z=0) AND (y DIV z=98) !'LSHIFT-HELP' key
  868.     about_buffer
  869.   ENDIF
  870.   IF (x=1) AND (y MOD z=0) AND (y DIV z=98) !'RSHIFT-HELP' key
  871.     about_midi
  872.   ENDIF
  873.   IF (x=6) AND (y MOD z=0) AND (y DIV z=98) !'CNTL-LSHIFT-HELP' key
  874.     about_modulation
  875.   ENDIF
  876.   IF (x=5) AND (y MOD z=0) AND (y DIV z=98) !'CNTL-RSHIFT-HELP' key
  877.     about_mod_car
  878.   ENDIF
  879.   IF (x=0) AND ((y MOD z=107) OR (y MOD z=75)) AND (y DIV z=37) !'k or K' key
  880.     about_key_equiv
  881.   ENDIF
  882.   IF (x=0) AND ((y MOD z=112) OR (y MOD z=80)) AND (y DIV z=25) !'p or P' key
  883.     about_editor_librarian
  884.   ENDIF
  885.   '
  886.   '
  887.   end_key_value:
  888.   DEFMOUSE 3
  889. RETURN
  890. '
  891. ' ***********************************************************************
  892. ' DISPLAY A POP-UP BOX LISTING ALL KEYBOARD EQUIVALENTS FOR GEM DROPDOWN
  893. ' ***********************************************************************
  894. '
  895. PROCEDURE about_key_equiv
  896.   '
  897.   x=120
  898.   y=30
  899.   lx=60
  900.   rx=610
  901.   IF rez=1
  902.     ty=15
  903.   ELSE
  904.     ty=10
  905.   ENDIF
  906.   by=180
  907.   IF rez=2
  908.     ty=ty+20
  909.     by=by+by+30-ty
  910.     y=70
  911.   ENDIF
  912.   SGET tempuse$
  913.   DEFFILL 0,2,8
  914.   DEFLINE 1,2
  915.   growbox(lx,ty,30,30,lx,ty,rx-lx,by-ty)
  916.   PBOX lx,ty,rx,by
  917.   BOX lx,ty,rx,by
  918.   DEFLINE 1,1
  919.   BOX lx+5,ty+2,rx-5,by-2
  920.   IF rez=1
  921.     DEFTEXT 1,9,0,6
  922.   ELSE
  923.     DEFTEXT 1,9,0,13
  924.   ENDIF
  925.   TEXT x,y,"FILE COMMANDS"
  926.   PRINT AT(10,6);"L - Load Patch"
  927.   PRINT AT(10,7);"S - Save Patch"
  928.   PRINT AT(10,9);"B - Build Patch"
  929.   PRINT AT(10,8);"D - Delete Patch"
  930.   PRINT AT(10,10);"CNTL/V - Verbose List"
  931.   PRINT AT(10,11);"Q - Quit Program"
  932.   IF rez=1
  933.     TEXT x,y+70,"BUFFER"
  934.   ELSE
  935.     TEXT x,y+120,"BUFFER"
  936.   ENDIF
  937.   PRINT AT(10,14);"V - Toggle View Mode"
  938.   PRINT AT(10,17);"K - This Screen"
  939.   PRINT AT(10,19);"UNDO - Clear Screen"
  940.   IF rez=1
  941.     TEXT x+220,y-2,"MIDI COMMANDS"
  942.   ELSE
  943.     TEXT x+220,y-10,"MIDI COMMANDS"
  944.   ENDIF
  945.   PRINT AT(35,5);"F1 - F5 - Send Banks 1 - 5"
  946.   PRINT AT(35,6);"ALT/F1 - ALT/F5 - Receive Banks 1 - 5"
  947.   PRINT AT(35,7);"F6 - Import Custom Drummer/.SYX"
  948.   PRINT AT(35,8);"ALT/F6 - Export Custom Drummer"
  949.   PRINT AT(35,9);"1 - 5(numeric keypad) - Change Voice Bank"
  950.   PRINT AT(35,10);"A - Set/Clear Audition Mode"
  951.   IF rez=1
  952.     TEXT x+220,y+62,"HELP"
  953.   ELSE
  954.     TEXT x+220,y+122,"HELP"
  955.   ENDIF
  956.   PRINT AT(35,14);"HELP - General"
  957.   PRINT AT(35,15);"CNTL/HELP - File"
  958.   PRINT AT(35,16);"LSHIFT/HELP - Buffer"
  959.   PRINT AT(35,17);"RSHIFT/HELP - MIDI"
  960.   PRINT AT(35,18);"CNTL/LSHIFT/HELP - Modulation"
  961.   PRINT AT(35,19);"CNTL/RSHIFT/HELP - Modulator/Carrier"
  962.   PRINT AT(35,20);"{-->} - Page Up"
  963.   PRINT AT(35,21);"{<--} - Page Down"
  964.   PRINT AT(35,22);"P - Program Credits"
  965.   HIDEM
  966.   a=MOUSEX
  967.   b=MOUSEY
  968.   DO
  969.     KEYTEST key
  970.     EXIT IF (MOUSEX<>a AND MOUSEY<>b) OR ((key=274792448) OR (key=6356992))
  971.   LOOP
  972.   SPUT tempuse$
  973.   shrinkbox(lx,ty,30,30,lx,ty,rx-lx,by-ty)
  974.   CLR tempuse$
  975.   DEFTEXT 1,0,0,10
  976.   check_viewmode
  977.   '
  978. RETURN
  979. '
  980. ' ***********************************************************************
  981. ' DISPLAY A POP-UP BOX INDICATING PROGRAM CREDITS
  982. ' ***********************************************************************
  983. '
  984. PROCEDURE about_editor_librarian
  985.   '
  986.   lx=100
  987.   rx=539
  988.   ty=15
  989.   by=199
  990.   IF rez=2
  991.     by=by+by-ty
  992.   ENDIF
  993.   SGET tempuse$
  994.   DIM linstyle%(14),credline$(14)
  995.   linstyle%(0)=1
  996.   linstyle%(1)=1
  997.   linstyle%(2)=0
  998.   linstyle%(3)=0
  999.   linstyle%(4)=4
  1000.   linstyle%(5)=4
  1001.   linstyle%(6)=4
  1002.   linstyle%(7)=0
  1003.   linstyle%(8)=0
  1004.   linstyle%(9)=0
  1005.   linstyle%(10)=0
  1006.   linstyle%(11)=4
  1007.   linstyle%(12)=4
  1008.   linstyle%(13)=4
  1009.   credline$(1)="   FOR THE PORTASOUND SERIES"
  1010.   credline$(2)="           Version 2.0     "
  1011.   credline$(3)=""
  1012.   credline$(4)="   Programmed in GFA BASIC 3.07"
  1013.   credline$(5)="     copyright 1991,1992,1993,1994"
  1014.   credline$(6)="        by Mike Silverstein"
  1015.   credline$(7)=""
  1016.   credline$(8)="If you like this MIDI shareware program,"
  1017.   credline$(9)="Please send a $7.00 contribution to:"
  1018.   credline$(10)=""
  1019.   credline$(11)="                   Mike Silverstein"
  1020.   credline$(12)="                  555 Rosewood Ave. #306"
  1021.   credline$(13)="                  Camarillo, CA 93010"
  1022.   DEFFILL 0,2,8
  1023.   DEFLINE 1,2
  1024.   growbox(lx,ty,20,20,lx,ty,rx-lx,by-ty)
  1025.   PBOX lx,ty,rx,by
  1026.   BOX lx,ty,rx,by
  1027.   DEFLINE 1,1
  1028.   BOX lx+5,ty+2,rx-5,by-2
  1029.   IF rez=2
  1030.     DEFTEXT 1,linstyle%(0),0,13
  1031.     offset=22
  1032.   ELSE
  1033.     DEFTEXT 1,linstyle%(0),0,7
  1034.     offset=10
  1035.   ENDIF
  1036.   IF rez=2
  1037.     TEXT lx+55,ty+20,"YAMAHA PSS PATCH EDITOR/LIBRARIAN"
  1038.   ELSE
  1039.     TEXT lx+55,ty+15,"YAMAHA PSS PATCH EDITOR/LIBRARIAN"
  1040.   ENDIF
  1041.   FOR x=1 TO 6
  1042.     DEFTEXT 1,linstyle%(x)
  1043.     TEXT lx+55,(ty+25+(x)*offset),credline$(x)
  1044.   NEXT x
  1045.   FOR x=7 TO 9
  1046.     DEFTEXT 1,linstyle%(x),0,6
  1047.     TEXT lx+55,(ty+25+(x)*offset),credline$(x)
  1048.   NEXT x
  1049.   FOR x=10 TO 13
  1050.     DEFTEXT 1,linstyle%(x),0,4
  1051.     TEXT lx+55,(ty+25+(x)*offset),credline$(x)
  1052.   NEXT x
  1053.   DEFTEXT 1,1,0,6
  1054.   IF demo_mode
  1055.     TEXT lx+182,by-9,"Continue              DEMO"
  1056.   ELSE
  1057.     TEXT lx+182,by-9,"Continue        REGISTERED"
  1058.   ENDIF
  1059.   DEFLINE 1,2
  1060.   BOX lx+175,by-19,rx-186,by-4
  1061.   HIDEM
  1062.   a=MOUSEX
  1063.   b=MOUSEY
  1064.   DO
  1065.     KEYTEST key
  1066.     EXIT IF (MOUSEX<>a AND MOUSEY<>b) OR ((key=274792448) OR (key=6356992))
  1067.   LOOP
  1068.   '
  1069.   DEFFILL 1,2,8
  1070.   PBOX lx+175,by-19,rx-186,by-4
  1071.   ERASE linstyle%()
  1072.   ERASE credline$()
  1073.   SPUT tempuse$
  1074.   CLR tempuse$,junk$
  1075.   shrinkbox(lx,ty,20,5,lx,ty,rx-lx,by-ty)
  1076.   '
  1077. RETURN
  1078. '
  1079. ' ***********************************************************************
  1080. ' THE NEXT 5 ROUTINES WILL PLACE THE BANK NUMBER IN THE ARRAY BASED ON
  1081. ' THE DROP-DOWN MENU SELECTION.  IT THEN CALLS THE CHECKSUM ROUTINE,
  1082. ' SENDS THE PATCH, AND SENDS A PROGRAM CHANGE TO THE YAMAHA BASED ON THE
  1083. ' BANK NUMBER.  IF THE AUDITION MODE IS SET, THEN THE PATCH DATA
  1084. ' CORRESPONDING TO THE CHANNEL/BANK # WILL BE PLAYED ACCORDINGLY.
  1085. ' ***********************************************************************
  1086. '
  1087. PROCEDURE send_1
  1088.   '
  1089.   a(5)=0                                !store bank #1
  1090.   checksum                              !calculate checksum byte
  1091.   send_patch                            !send the patch
  1092.   OUT 3,&HC0                            !send bank 1 program change
  1093.   OUT 3,100
  1094.   IF audition_flag=TRUE
  1095.     PAUSE 20
  1096.     OUT 3,&H90                        !MIDI note on, channel 1
  1097.     OUT 3,36                          !Play a C1, channel 1
  1098.     OUT 3,64                          !Medium Velocity
  1099.     pitch=1
  1100.     popup_audition(pitch)
  1101.     OUT 3,&H80                        !MIDI note off, channel 1
  1102.     OUT 3,36                          !Release C1, channel 1
  1103.     OUT 3,64                          !Medium Velocity
  1104.     OUT 3,&H90                        !MIDI note on, channel 1
  1105.     OUT 3,60                          !Play a C3,channel 1
  1106.     OUT 3,64                          !Medium Velocity
  1107.     pitch=2
  1108.     popup_audition(pitch)
  1109.     OUT 3,&H80                        !MIDI note off,channel 1
  1110.     OUT 3,60                          !Release C3, channel 1
  1111.     OUT 3,64                          !Medium Velocity
  1112.     OUT 3,&H90                        !MIDI note on, channel 1
  1113.     OUT 3,84                          !Play a C5, channel 1
  1114.     OUT 3,64                          !Medium Velocity
  1115.     pitch=3
  1116.     popup_audition(pitch)
  1117.     OUT 3,&H80                        !MIDI note off, channel 1
  1118.     OUT 3,84                          !Release C5, channel 1
  1119.     OUT 3,64                          !Medium Velocity
  1120.   ENDIF
  1121.   '
  1122. RETURN
  1123. '
  1124. PROCEDURE send_2
  1125.   '
  1126.   a(5)=1                                !store bank #2
  1127.   checksum                              !calculate checksum byte
  1128.   send_patch                            !send the patch
  1129.   OUT 3,&HC1                            !send bank 2 program change
  1130.   OUT 3,101
  1131.   IF audition_flag=TRUE
  1132.     PAUSE 20
  1133.     OUT 3,&H91                        !MIDI note on, channel 2
  1134.     OUT 3,36                          !Play a C1, channel 2
  1135.     OUT 3,64                          !Medium Velocity
  1136.     pitch=1
  1137.     popup_audition(pitch)
  1138.     OUT 3,&H81                        !MIDI note off, channel 2
  1139.     OUT 3,36                          !Release C1, channel 2
  1140.     OUT 3,64                          !Medium Velocity
  1141.     OUT 3,&H91                        !MIDI note on, channel 2
  1142.     OUT 3,60                          !Play a C3,channel 2
  1143.     OUT 3,64                          !Medium Velocity
  1144.     pitch=2
  1145.     popup_audition(pitch)
  1146.     OUT 3,&H81                        !MIDI note off,channel 2
  1147.     OUT 3,60                          !Release C3, channel 2
  1148.     OUT 3,64                          !Medium Velocity
  1149.     OUT 3,&H91                        !MIDI note on, channel 2
  1150.     OUT 3,84                          !Play a C5, channel 2
  1151.     OUT 3,64                          !Medium Velocity
  1152.     pitch=3
  1153.     popup_audition(pitch)
  1154.     OUT 3,&H81                        !MIDI note off, channel 2
  1155.     OUT 3,84                          !Release C5, channel 2
  1156.     OUT 3,64                          !Medium Velocity
  1157.   ENDIF
  1158.   '
  1159. RETURN
  1160. '
  1161. PROCEDURE send_3
  1162.   '
  1163.   a(5)=2                                !store bank #3
  1164.   checksum                              !calculate checksum byte
  1165.   send_patch                            !send the patch
  1166.   OUT 3,&HC2                            !send bank 3 program change
  1167.   OUT 3,102
  1168.   IF audition_flag=TRUE
  1169.     PAUSE 20
  1170.     OUT 3,&H92                        !MIDI note on, channel 3
  1171.     OUT 3,36                          !Play a C1, channel 3
  1172.     OUT 3,64                          !Medium Velocity
  1173.     pitch=1
  1174.     popup_audition(pitch)
  1175.     OUT 3,&H82                        !MIDI note off, channel 3
  1176.     OUT 3,36                          !Release C1, channel 3
  1177.     OUT 3,64                          !Medium Velocity
  1178.     OUT 3,&H92                        !MIDI note on, channel 3
  1179.     OUT 3,60                          !Play a C3,channel 3
  1180.     OUT 3,64                          !Medium Velocity
  1181.     pitch=2
  1182.     popup_audition(pitch)
  1183.     OUT 3,&H82                        !MIDI note off,channel 3
  1184.     OUT 3,60                          !Release C3, channel 3
  1185.     OUT 3,64                          !Medium Velocity
  1186.     OUT 3,&H92                        !MIDI note on, channel 3
  1187.     OUT 3,84                          !Play a C5, channel 3
  1188.     OUT 3,64                          !Medium Velocity
  1189.     pitch=3
  1190.     popup_audition(pitch)
  1191.     OUT 3,&H82                        !MIDI note off, channel 3
  1192.     OUT 3,84                          !Release C5, channel 3
  1193.     OUT 3,64                          !Medium Velocity
  1194.   ENDIF
  1195.   '
  1196. RETURN
  1197. '
  1198. PROCEDURE send_4
  1199.   '
  1200.   a(5)=3                                !store bank #4
  1201.   checksum                              !calculate checksum byte
  1202.   send_patch                            !send the patch
  1203.   OUT 3,&HC3                            !send bank 4 program change
  1204.   OUT 3,103
  1205.   IF audition_flag=TRUE
  1206.     PAUSE 20
  1207.     OUT 3,&H93                        !MIDI note on, channel 4
  1208.     OUT 3,36                          !Play a C1, channel 4
  1209.     OUT 3,64                          !Medium Velocity
  1210.     pitch=1
  1211.     popup_audition(pitch)
  1212.     OUT 3,&H83                        !MIDI note off, channel 4
  1213.     OUT 3,36                          !Release C1, channel 4
  1214.     OUT 3,64                          !Medium Velocity
  1215.     OUT 3,&H93                        !MIDI note on, channel 4
  1216.     OUT 3,60                          !Play a C3,channel 4
  1217.     OUT 3,64                          !Medium Velocity
  1218.     pitch=2
  1219.     popup_audition(pitch)
  1220.     OUT 3,&H83                        !MIDI note off,channel 4
  1221.     OUT 3,60                          !Release C3, channel 4
  1222.     OUT 3,64                          !Medium Velocity
  1223.     OUT 3,&H93                        !MIDI note on, channel 4
  1224.     OUT 3,84                          !Play a C5, channel 4
  1225.     OUT 3,64                          !Medium Velocity
  1226.     pitch=3
  1227.     popup_audition(pitch)
  1228.     OUT 3,&H83                        !MIDI note off, channel 4
  1229.     OUT 3,84                          !Release C5, channel 4
  1230.     OUT 3,64                          !Medium Velocity
  1231.   ENDIF
  1232.   '
  1233. RETURN
  1234. '
  1235. PROCEDURE send_5
  1236.   '
  1237.   a(5)=4                                !store bank #5
  1238.   checksum                              !calculate checksum byte
  1239.   send_patch                            !send the patch
  1240.   OUT 3,&HC4                            !send bank 5 program change
  1241.   OUT 3,104
  1242.   IF audition_flag=TRUE
  1243.     PAUSE 20
  1244.     OUT 3,&H94                        !MIDI note on, channel 5
  1245.     OUT 3,36                          !Play a C1, channel 5
  1246.     OUT 3,64                          !Medium Velocity
  1247.     pitch=1
  1248.     popup_audition(pitch)
  1249.     OUT 3,&H84                        !MIDI note off, channel 5
  1250.     OUT 3,36                          !Release C1, channel 5
  1251.     OUT 3,64                          !Medium Velocity
  1252.     OUT 3,&H94                        !MIDI note on, channel 5
  1253.     OUT 3,60                          !Play a C3,channel 5
  1254.     OUT 3,64                          !Medium Velocity
  1255.     pitch=2
  1256.     popup_audition(pitch)
  1257.     OUT 3,&H84                        !MIDI note off,channel 5
  1258.     OUT 3,60                          !Release C3, channel 5
  1259.     OUT 3,64                          !Medium Velocity
  1260.     OUT 3,&H94                        !MIDI note on, channel 5
  1261.     OUT 3,84                          !Play a C5, channel 5
  1262.     OUT 3,64                          !Medium Velocity
  1263.     pitch=3
  1264.     popup_audition(pitch)
  1265.     OUT 3,&H84                        !MIDI note off, channel 5
  1266.     OUT 3,84                          !Release C5, channel 5
  1267.     OUT 3,64                          !Medium Velocity
  1268.   ENDIF
  1269.   '
  1270. RETURN
  1271. '
  1272. ' ***********************************************************************
  1273. ' MIDI-READY-PROMPT ALERTS THE USER TO PREPARE THE YAMAHA INSTRUMENT FOR
  1274. ' A MEMORY BULK DUMP TO THE ST.  BASED ON THE BUTTON READ FROM THE
  1275. ' DROP-DOWN MENU, THE APPROPRIATE RECEIVE ROUTINE IS CALLED.  THE VIEW
  1276. ' BUFFER IS THEN DISPLAYED DEPENDING ON THE CURRENT VIEW MODE. THIS ALSO
  1277. ' OCCURS WHEN THE USER BAILS OUT OF THE BULK DUMP ROUTINES.
  1278. ' ***********************************************************************
  1279. '
  1280. PROCEDURE midi_ready_prompt(VAR bank)
  1281.   '
  1282.   ALERT 1,"Is Yamaha Keyboard Ready?",1,"yes|no",receive_prompt
  1283.   SELECT receive_prompt
  1284.   CASE 1
  1285.     ALERT 1,"Please transmit via Bulk Dump.",1,"OK",ok_prompt
  1286.     SELECT bank
  1287.     CASE 1
  1288.       receive_1
  1289.       check_viewmode
  1290.     CASE 2
  1291.       receive_2
  1292.       check_viewmode
  1293.     CASE 3
  1294.       receive_3
  1295.       check_viewmode
  1296.     CASE 4
  1297.       receive_4
  1298.       check_viewmode
  1299.     CASE 5
  1300.       receive_5
  1301.       check_viewmode
  1302.     ENDSELECT
  1303.   CASE 2                        ! User bailed out
  1304.     check_viewmode
  1305.   ENDSELECT
  1306.   DEFMOUSE 3                    ! reinitialize mouse to pointing hand
  1307.   '
  1308. RETURN
  1309. '
  1310. ' ***********************************************************************
  1311. ' THE NEXT 5 ROUTINES SET THE BANK NUMBER BASED ON THE DROP-DOWN MENU
  1312. ' SELECTION. THE RECEIVE-MIDI ROUTINE IS CALLED WITH THE PROPER BANK
  1313. ' NUMBER PASSED, A 4 SECOND DELAY IS ISSUED TO ALLOW TIME FOR THE ENTIRE
  1314. ' BULK DUMP TO GET THROUGH, AND A PROGRAM CHANGE IS SENT BASED ON THE
  1315. ' BANK NUMBER.
  1316. ' ***********************************************************************
  1317. '
  1318. PROCEDURE receive_1
  1319.   '
  1320.   bank_number=0
  1321.   receive_midi(bank_number)
  1322.   DELAY 4
  1323.   OUT 3,&HC0                     !send bank 1 program change
  1324.   OUT 3,100
  1325.   '
  1326. RETURN
  1327. '
  1328. PROCEDURE receive_2
  1329.   '
  1330.   bank_number=1
  1331.   receive_midi(bank_number)
  1332.   DELAY 4
  1333.   OUT 3,&HC1                            !send bank 2 program change
  1334.   OUT 3,101
  1335.   '
  1336. RETURN
  1337. '
  1338. PROCEDURE receive_3
  1339.   '
  1340.   bank_number=2
  1341.   receive_midi(bank_number)
  1342.   DELAY 4
  1343.   OUT 3,&HC2                            !send bank 3 program change
  1344.   OUT 3,102
  1345.   '
  1346. RETURN
  1347. '
  1348. PROCEDURE receive_4
  1349.   '
  1350.   bank_number=3
  1351.   receive_midi(bank_number)
  1352.   DELAY 4
  1353.   OUT 3,&HC3                            !send bank 4 program change
  1354.   OUT 3,103
  1355.   '
  1356. RETURN
  1357. '
  1358. PROCEDURE receive_5
  1359.   '
  1360.   bank_number=4
  1361.   receive_midi(bank_number)
  1362.   DELAY 4
  1363.   OUT 3,&HC4                            !send bank 5 program change
  1364.   OUT 3,104
  1365.   '
  1366. RETURN
  1367. '
  1368. ' ***********************************************************************
  1369. ' RECEIVE-MIDI CALLS CHANGE-MIDI-BUFF TO REDEFINE THE SIZE OF THE SYSTEM
  1370. ' MIDI BUFFER TO ALLOW FOR A 512 BYTE BULK DUMP OF ALL PATCH SOUNDS. IT
  1371. ' THEN SETS UP AN ARRAY FOR READING INCOMING SYSTEM EXCLUSIVE MIDI DATA.
  1372. ' A FLAG IS USED TO SET UP A LOOP WHERE A SPECIFIC 4 BYTE SEQUENCE IS
  1373. ' USED TO DETERMINE WHICH BANK TO RECEIVE BASED ON THE BANK NUMBER
  1374. ' SELECTED FROM THE DROP-DOWN MENU.  ONCE THIS SEQUENCE IS DETERMINED,
  1375. ' THE NEXT 65 BYTES WILL CONTAIN ALL DATA PARAMETERS FOR THE PATCH
  1376. ' INCLUDING A CHECKSUM BYTE.  THE RECEIVE-CHECKSUM ROUTINE IS CALLED
  1377. ' AND THE INCOMING MIDI ARRAY BUFFER IS ERASED FOR THE NEXT TIME THRU.
  1378. ' FINALLY, THE RECEIVED PATCH IS PROCESSED INTO THE SYSTEM GFA BASIC
  1379. ' PARAMETER VALUES.  DURING RECEPTION, THE USER IS NOTIFIED THAT THE
  1380. ' INCOMING MIDI DATA IS BEING RECEIVED.
  1381. ' ***********************************************************************
  1382. '
  1383. PROCEDURE receive_midi(bank_number)
  1384.   '
  1385.   CLS                                   !clear screen
  1386.   LOCATE 25,15
  1387.   PRINT "Waiting for MIDI.........."    !display user prompt for bulk dump
  1388.   midi.buff.size=512                    !new size = 512 bytes for patches
  1389.   change_midi_buff(midi.buff.size)      !redefine system MIDI buffsize
  1390.   DIM p(70)                             !Initialize incoming MIDI array
  1391.   receive_flag=FALSE                    !clear loop flag
  1392.   WHILE NOT receive_flag                !Search for 4 byte sequence
  1393.     IF HEX$(INP(3))="76" THEN
  1394.       IF HEX$(INP(3))="0" THEN
  1395.         IF HEX$(INP(3))="0" THEN
  1396.           IF HEX$(INP(3))=STR$(bank_number) THEN
  1397.             FOR i=1 TO 65               !Collect all patch data
  1398.               p(i)=INP(3)
  1399.               PRINT AT(30,0);"RECEIVING......."; !Notify user
  1400.               PRINT AT(30,0);"                ";
  1401.             NEXT i
  1402.             receive_flag=TRUE           !set loop flag
  1403.             PRINT AT(30,0);"RECEIVED BANK ";STR$(bank_number+1);
  1404.           ENDIF
  1405.         ENDIF
  1406.       ENDIF
  1407.     ENDIF
  1408.   WEND
  1409.   n=6                         !point to 1st byte in buffer
  1410.   sum=bank_number             !checksum includes bank #
  1411.   receive_checksum            !copy MIDI array to system buff and checksum
  1412.   ERASE p()                   !erase MIDI array for next time thru
  1413.   receiving=TRUE              !set flag for file checking
  1414.   received=TRUE               !set flag for editing parameters
  1415.   process_data                !process all bytes to GFA parameter values
  1416.   received=FALSE              !reset flag for editing parameters
  1417.   restore_midi_buffer
  1418.   '
  1419. RETURN
  1420. '
  1421. ' ***********************************************************************
  1422. ' CHANGE-MIDI-BUFF REDEFINES THE ATARI DEFAULT BUFFER (128 BYTES) TO
  1423. ' A NEW SIZE SO THAT A MEMORY BULK DUMP MAY BE PROPERLY RECEIVED INTO
  1424. ' THE SYSTEM MIDI ARRAY.  - Not called anymore!!
  1425. ' ***********************************************************************
  1426. '
  1427. PROCEDURE change_midi_buff(midi.buff.size)
  1428.   '
  1429.   midi.ptr=XBIOS(14,2)                  !get system MIDI buffer data record
  1430.   midi.buff.adr=LPEEK(midi.ptr)         !get address of original buffer
  1431.   ERASE midi.buff()                     !clear the default size
  1432.   DIM midi.buff(midi.buff.size-1)       !change size to a new value
  1433.   LPOKE midi.ptr,VARPTR(midi.buff(0))   !point to starting address
  1434.   DPOKE midi.ptr+4,(midi.buff.size)     !write new size
  1435.   DPOKE midi.ptr+6,0                    !buffer head
  1436.   DPOKE midi.ptr+8,0                    !buffer tail
  1437.   DPOKE midi.ptr+10,0                   !low mark (not used)
  1438.   DPOKE midi.ptr+12,(midi.buff.size-1)  !high mark (not used)
  1439.   PRINT AT(1,1);"Established a ";midi.buff.size;" byte MIDI buffer."
  1440.   ' PRINT AT(25,15);"Waiting for MIDI.........." !display prompt for bulk dump
  1441.   '
  1442. RETURN
  1443. '
  1444. PROCEDURE restore_midi_buffer
  1445.   '
  1446.   old.adr=XBIOS(14,2)             ! get system MIDI data record
  1447.   LPOKE old.adr,midi.buff.adr     ! point to default address
  1448.   DPOKE old.adr+4,128             ! restore default size back
  1449.   DPOKE old.adr+6,0               ! restore other old values
  1450.   DPOKE old.adr+8,0
  1451.   DPOKE old.adr+10,0
  1452.   DPOKE old.adr+12,127
  1453.   '
  1454. RETURN
  1455. '
  1456. PROCEDURE receive_drummer
  1457.   ' ***********************************************************************
  1458.   ' RECEIVE_DRUMMER - THIS ROUTINE PROMPTS THE USER TO PLACE THE
  1459.   ' SYNTHESIZER IN BULK DUMP MODE.  IT THEN CALLS CHANGE_MIDI_BUFF TO
  1460.   ' SET A NEW SIZE FOR THE SYSTEM MIDI BUFFER TO A SIZE THAT WILL ALLOW
  1461.   ' CUSTOM DRUMMER INFO (THE LAST SYSEX MESSAGE, AFTER 13 KBYTES OR SO).
  1462.   ' AFTER THE USER DOES THE MEMORY BULK DUMP, AN ARRAY WILL BE FILLED
  1463.   ' WITH THE DRUMMER DATA AND THE FILE SELECTOR WILL BE USED TO SAVE THE
  1464.   ' ARRAY CONTAINING CUSTOM DRUMMER INFO TO A DISK FILE WITH A .SYX
  1465.   ' EXTENSION.
  1466.   ' ***********************************************************************
  1467.   '
  1468.   ALERT 1,"Is Yamaha Keyboard Ready?",1,"yes|no",receive_prompt
  1469.   SELECT receive_prompt
  1470.   CASE 1
  1471.     ALERT 1,"Please transmit via Bulk Dump.",1,"OK",ok_prompt
  1472.     CLS                                   !clear screen
  1473.     LOCATE 25,15
  1474.     PRINT "Waiting for Drum Info....."    !display user prompt for bulk dump
  1475.     midi.buff.size=13800                  !new size = 14K bytes for drummer
  1476.     change_midi_buff(midi.buff.size)      !redefine system MIDI buffsize
  1477.     DIM d(687)                            !Initialize incoming MIDI array
  1478.     receive_flag=FALSE                    !clear loop flag
  1479.     WHILE NOT receive_flag                !Search for 4 byte sequence
  1480.       IF HEX$(INP(3))="76" THEN
  1481.         IF HEX$(INP(3))="3" THEN
  1482.           FOR i=1 TO 686               !Collect all patch data
  1483.             d(i)=INP(3)
  1484.             PRINT AT(30,0);"RECEIVING......."; !Notify user
  1485.             PRINT AT(30,0);"                ";
  1486.           NEXT i
  1487.           receive_flag=TRUE           !set loop flag
  1488.         ENDIF
  1489.       ENDIF
  1490.     WEND
  1491.     restore_midi_buffer
  1492.     n=686                        ! set array size
  1493.     DIM b(690)
  1494.     b(0)=240                    ! define MIDI Status byte (&HF0)
  1495.     b(1)=67                     ! define MIDI Instrument ID for Yamaha (&H43)
  1496.     b(2)=118                    ! define MIDI Class byte (&H76)
  1497.     b(3)=3                      ! define MIDI Format # (&H03)
  1498.     FOR i=4 TO 690
  1499.       b(i)=d(i-3)
  1500.     NEXT i
  1501.     n=0                                   !point to beginning of buffer
  1502.     patch_buffer=MALLOC(690)              !reserve 690 bytes for export
  1503.     FOR i=1 TO 690                         !clear patch buffer
  1504.       POKE patch_buffer,0
  1505.       INC patch_buffer
  1506.     NEXT i
  1507.     patch_buffer=patch_buffer-690          !reset pointer
  1508.     FOR i=1 TO 690
  1509.       POKE patch_buffer,b(n)              !write MIDI parameters to buffer
  1510.       INC patch_buffer                    !update buffer pointer
  1511.       INC n                               !update data pointer
  1512.     NEXT i
  1513.     patch_buffer=patch_buffer-690          !reset buffer pointer
  1514.     path$=DIR$(0)
  1515.     FILESELECT path$+"\*.*","",patch_name$    !call file selector
  1516.     IF RIGHT$(patch_name$)="\" OR patch_name$="" THEN
  1517.       GOTO end_drummer_save                 !skip for OK or Cancel button
  1518.     ENDIF
  1519.     BSAVE patch_name$+".SYX",patch_buffer,690     !save to disk
  1520.     '
  1521.     end_drummer_save:
  1522.     VOID MFREE(patch_buffer)              !free buffer area
  1523.     ERASE d()
  1524.     ERASE b()
  1525.     '
  1526.   CASE 2                        ! User bailed out
  1527.     check_viewmode
  1528.   ENDSELECT
  1529. RETURN
  1530. '
  1531. ' ***********************************************************************
  1532. ' SEND_DRUMMER - THIS ROUTINE SENDS A SYSEX CUSTOM DRUMMER MESSAGE BY
  1533. ' FIRST PROMPTING THE USER TO SELECT A .SYX FILE.  IT THEN CHECKS TO
  1534. ' MAKE SURE THAT THE FIRST BYTE IS A VALID F0 (START OF SYSEX) AND THEN
  1535. ' SENDS ALL 690 BYTES WHICH MAKE UP THE CUSTOM DRUMMER MESSAGE.  NOTE
  1536. ' THAT THE .SYX FILE CAN ALSO BE A PATCH FILE AS WELL.  IF THE AUDITION
  1537. ' MODE IS SET, THEN IF ITS PATCH DATA, THE CORRESPONDING BANK/CHANNEL #
  1538. ' WILL BE PLAYED.  IF ITS DRUM DATA, THEN MIDI START/STOP COMMANDS WILL
  1539. ' BE ISSUED APPROPRIATELY.
  1540. ' ***********************************************************************
  1541. '
  1542. PROCEDURE send_drummer
  1543.   n=0
  1544.   DIM b(690)
  1545.   patch_buffer=MALLOC(690)    !reserve 690 bytes for patch
  1546.   FOR i=1 TO 690              !clear buffer
  1547.     POKE patch_buffer,0
  1548.     INC patch_buffer
  1549.   NEXT i
  1550.   patch_buffer=patch_buffer-690             !reset pointer
  1551.   do_import:
  1552.   path$=DIR$(0)
  1553.   FILESELECT path$+"\*.*","",patch_name$    !call file selector"
  1554.   IF RIGHT$(patch_name$)="\" OR patch_name$="" THEN
  1555.     GOTO end_drummer_load                   !skip for OK or Cancel button
  1556.   ENDIF
  1557.   IF NOT EXIST(patch_name$)                 !check for user error
  1558.     CLS
  1559.     PRINT "Error: File Doesn't exist!!!"
  1560.     GOTO do_import
  1561.   ENDIF
  1562.   BLOAD patch_name$,patch_buffer        !load patch from disk
  1563.   FOR i=0 TO 689
  1564.     b(n)=PEEK(patch_buffer)             !write MIDI parameters to buffer
  1565.     INC patch_buffer                    !update buffer pointer
  1566.     INC n                               !update data pointer
  1567.   NEXT i
  1568.   IF HEX$(b(0))<>"F0" THEN              !Check for start of SYSEX
  1569.     ALERT 1,"File error!.",1,"OK",ok_prompt
  1570.     GOTO end_drummer_load
  1571.   ENDIF
  1572.   patch_buffer=patch_buffer-690         !reset pointer
  1573.   CLS                                   !clear screen
  1574.   LOCATE 25,15
  1575.   PRINT "Sending SYX Info....."    !display user prompt for bulk dump
  1576.   n=0                    !point to beginning of buffer
  1577.   OUT 3,&HFC             !Send MIDI STOP
  1578.   IF b(3)=3 THEN
  1579.     limit=689            !Must be drummer info
  1580.   ELSE
  1581.     limit=71             !Must be patch info
  1582.   ENDIF
  1583.   FOR i=0 TO limit
  1584.     OUT 3,b(n)           !send all SYSEX data bytes to synth
  1585.     INC n
  1586.   NEXT i
  1587.   IF b(3)=3 THEN
  1588.     OUT 3,&HFA           !Send MIDI START if custom drummer
  1589.   ENDIF
  1590.   IF b(5)=0 AND limit=71 THEN
  1591.     OUT 3,&HC0           !send bank 1 program change
  1592.     OUT 3,100
  1593.     IF audition_flag=TRUE
  1594.       PAUSE 20
  1595.       OUT 3,&H90                        !MIDI note on, channel 1
  1596.       OUT 3,36                          !Play a C1, channel 1
  1597.       OUT 3,64                          !Medium Velocity
  1598.       pitch=1
  1599.       popup_audition(pitch)
  1600.       OUT 3,&H80                        !MIDI note off, channel 1
  1601.       OUT 3,36                          !Release C1, channel 1
  1602.       OUT 3,64                          !Medium Velocity
  1603.       OUT 3,&H90                        !MIDI note on, channel 1
  1604.       OUT 3,60                          !Play a C3,channel 1
  1605.       OUT 3,64                          !Medium Velocity
  1606.       pitch=2
  1607.       popup_audition(pitch)
  1608.       OUT 3,&H80                        !MIDI note off,channel 1
  1609.       OUT 3,60                          !Release C3, channel 1
  1610.       OUT 3,64                          !Medium Velocity
  1611.       OUT 3,&H90                        !MIDI note on, channel 1
  1612.       OUT 3,84                          !Play a C5, channel 1
  1613.       OUT 3,64                          !Medium Velocity
  1614.       pitch=3
  1615.       popup_audition(pitch)
  1616.       OUT 3,&H80                        !MIDI note off, channel 1
  1617.       OUT 3,84                          !Release C5, channel 1
  1618.       OUT 3,64                          !Medium Velocity
  1619.     ENDIF
  1620.   ENDIF
  1621.   IF b(5)=1 AND limit=71 THEN
  1622.     OUT 3,&HC1           !send bank 2 program change
  1623.     OUT 3,101
  1624.     IF audition_flag=TRUE
  1625.       PAUSE 20
  1626.       OUT 3,&H91                        !MIDI note on, channel 2
  1627.       OUT 3,36                          !Play a C1, channel 2
  1628.       OUT 3,64                          !Medium Velocity
  1629.       pitch=1
  1630.       popup_audition(pitch)
  1631.       OUT 3,&H81                        !MIDI note off, channel 2
  1632.       OUT 3,36                          !Release C1, channel 2
  1633.       OUT 3,64                          !Medium Velocity
  1634.       OUT 3,&H91                        !MIDI note on, channel 2
  1635.       OUT 3,60                          !Play a C3,channel 1
  1636.       OUT 3,64                          !Medium Velocity
  1637.       pitch=2
  1638.       popup_audition(pitch)
  1639.       OUT 3,&H81                        !MIDI note off,channel 2
  1640.       OUT 3,60                          !Release C3, channel 2
  1641.       OUT 3,64                          !Medium Velocity
  1642.       OUT 3,&H91                        !MIDI note on, channel 2
  1643.       OUT 3,84                          !Play a C5, channel 2
  1644.       OUT 3,64                          !Medium Velocity
  1645.       pitch=3
  1646.       popup_audition(pitch)
  1647.       OUT 3,&H81                        !MIDI note off, channel 2
  1648.       OUT 3,84                          !Release C5, channel 2
  1649.       OUT 3,64                          !Medium Velocity
  1650.     ENDIF
  1651.   ENDIF
  1652.   IF b(5)=2 AND limit=71 THEN
  1653.     OUT 3,&HC2           !send bank 3 program change
  1654.     OUT 3,102
  1655.     IF audition_flag=TRUE
  1656.       PAUSE 20
  1657.       OUT 3,&H92                        !MIDI note on, channel 3
  1658.       OUT 3,36                          !Play a C1, channel 3
  1659.       OUT 3,64                          !Medium Velocity
  1660.       pitch=1
  1661.       popup_audition(pitch)
  1662.       OUT 3,&H82                        !MIDI note off, channel 3
  1663.       OUT 3,36                          !Release C1, channel 3
  1664.       OUT 3,64                          !Medium Velocity
  1665.       OUT 3,&H92                        !MIDI note on, channel 3
  1666.       OUT 3,60                          !Play a C3,channel 3
  1667.       OUT 3,64                          !Medium Velocity
  1668.       pitch=2
  1669.       popup_audition(pitch)
  1670.       OUT 3,&H82                        !MIDI note off,channel 3
  1671.       OUT 3,60                          !Release C3, channel 3
  1672.       OUT 3,64                          !Medium Velocity
  1673.       OUT 3,&H92                        !MIDI note on, channel 3
  1674.       OUT 3,84                          !Play a C5, channel 3
  1675.       OUT 3,64                          !Medium Velocity
  1676.       pitch=3
  1677.       popup_audition(pitch)
  1678.       OUT 3,&H82                        !MIDI note off, channel 3
  1679.       OUT 3,84                          !Release C5, channel 3
  1680.       OUT 3,64                          !Medium Velocity
  1681.     ENDIF
  1682.   ENDIF
  1683.   IF b(5)=3 AND limit=71 THEN
  1684.     OUT 3,&HC3           !send bank 4 program change
  1685.     OUT 3,103
  1686.     IF audition_flag=TRUE
  1687.       PAUSE 20
  1688.       OUT 3,&H93                        !MIDI note on, channel 4
  1689.       OUT 3,36                          !Play a C1, channel 4
  1690.       OUT 3,64                          !Medium Velocity
  1691.       pitch=1
  1692.       popup_audition(pitch)
  1693.       OUT 3,&H83                        !MIDI note off, channel 4
  1694.       OUT 3,36                          !Release C1, channel 4
  1695.       OUT 3,64                          !Medium Velocity
  1696.       OUT 3,&H93                        !MIDI note on, channel 4
  1697.       OUT 3,60                          !Play a C3,channel 4
  1698.       OUT 3,64                          !Medium Velocity
  1699.       pitch=2
  1700.       popup_audition(pitch)
  1701.       OUT 3,&H83                        !MIDI note off,channel 4
  1702.       OUT 3,60                          !Release C3, channel 4
  1703.       OUT 3,64                          !Medium Velocity
  1704.       OUT 3,&H93                        !MIDI note on, channel 4
  1705.       OUT 3,84                          !Play a C5, channel 4
  1706.       OUT 3,64                          !Medium Velocity
  1707.       pitch=3
  1708.       popup_audition(pitch)
  1709.       OUT 3,&H83                        !MIDI note off, channel 4
  1710.       OUT 3,84                          !Release C5, channel 4
  1711.       OUT 3,64                          !Medium Velocity
  1712.     ENDIF
  1713.   ENDIF
  1714.   IF b(5)=4 AND limit=71 THEN
  1715.     OUT 3,&HC4           !send bank 5 program change
  1716.     OUT 3,104
  1717.     IF audition_flag=TRUE
  1718.       PAUSE 20
  1719.       OUT 3,&H94                        !MIDI note on, channel 5
  1720.       OUT 3,36                          !Play a C1, channel 5
  1721.       OUT 3,64                          !Medium Velocity
  1722.       pitch=1
  1723.       popup_audition(pitch)
  1724.       OUT 3,&H84                        !MIDI note off, channel 5
  1725.       OUT 3,36                          !Release C1, channel 5
  1726.       OUT 3,64                          !Medium Velocity
  1727.       OUT 3,&H94                        !MIDI note on, channel 5
  1728.       OUT 3,60                          !Play a C3,channel 5
  1729.       OUT 3,64                          !Medium Velocity
  1730.       pitch=2
  1731.       popup_audition(pitch)
  1732.       OUT 3,&H84                        !MIDI note off,channel 5
  1733.       OUT 3,60                          !Release C3, channel 5
  1734.       OUT 3,64                          !Medium Velocity
  1735.       OUT 3,&H94                        !MIDI note on, channel 5
  1736.       OUT 3,84                          !Play a C5, channel 5
  1737.       OUT 3,64                          !Medium Velocity
  1738.       pitch=3
  1739.       popup_audition(pitch)
  1740.       OUT 3,&H84                        !MIDI note off, channel 5
  1741.       OUT 3,84                          !Release C5, channel 5
  1742.       OUT 3,64                          !Medium Velocity
  1743.     ENDIF
  1744.   ENDIF
  1745.   end_drummer_load:
  1746.   VOID MFREE(patch_buffer)              !free buffer area
  1747.   receiving=TRUE                !set flag to clear filename from patch buffer
  1748.   ERASE b()
  1749.   DEFMOUSE 3
  1750. RETURN
  1751. '
  1752. ' ***********************************************************************
  1753. ' RECEIVE-CHECKSUM TRANSFERS THE RECEIVED MIDI ARRAY TO THE SYSTEM MIDI
  1754. ' BUFFER AND PERFORMS A 7 BIT CHECKSUM TO INSURE DATA INTEGRITY OVER
  1755. ' THE MIDI CABLES. AN ALERT BOX IS DISPLAYED FOR AN ERROR CONDITION.
  1756. ' ***********************************************************************
  1757. '
  1758. PROCEDURE receive_checksum
  1759.   '
  1760.   FOR i=1 TO 66               !Copy received MIDI array to buffer
  1761.     a(n)=p(i)
  1762.     EXIT IF n=70
  1763.     sum=sum+a(n)              !add all data elements including bank number
  1764.     INC n
  1765.   NEXT i
  1766.   IF sum MOD 128<>0
  1767.     checksum=128-(sum AND &H7F) !checksum is 7 bits 2's complement
  1768.   ELSE
  1769.     checksum=0                  !insure checksum is not multiple of 128
  1770.   ENDIF
  1771.   IF a(70)<>checksum THEN     !71st element points to checksum byte
  1772.     ALERT 1,"Checksum Error!",1,"OK",b
  1773.   ENDIF
  1774.   '
  1775. RETURN
  1776. '
  1777. ' ***********************************************************************
  1778. ' CHECKSUM WILL CALCULATE THE REQUIRED 7 BIT 2'S COMPLEMENT OFF ALL
  1779. ' DATA ELEMENTS IN THE SYSTEM BUFFER EXCEPT THE 4 BYTE HEADER. EACH
  1780. ' ELEMENT IS ADDED TO THE SUM VARIABLE WHICH AND THE 8TH BIT IS MASKED
  1781. ' OFF.  THE RESULT IS STORED IN THE 71ST ELEMENT OF THE 72 BYTE PATCH
  1782. ' BUFFER FOR TRANSMISSION TO THE YAMAHA INSTRUMENT.  THIS ROUTINE INSURES
  1783. ' THAT IF THE TOTAL SUM IS A MULTIPLE OF 128 (80 HEX), THE CHECKSUM IS 0.
  1784. ' ***********************************************************************
  1785. '
  1786. PROCEDURE checksum
  1787.   '
  1788.   n=4                    !point to 1st data element in buffer
  1789.   sum=0                  !initialize sum
  1790.   FOR i=1 TO 66
  1791.     sum=sum+a(n)         !add all data bytes
  1792.     INC n
  1793.   NEXT i
  1794.   IF sum MOD 128<>0
  1795.     checksum=128-(sum AND &H7F)  !checksum is 7 bits 2's complement
  1796.   ELSE
  1797.     checksum=0           !insure sum is not a multiple of 128
  1798.   ENDIF
  1799.   a(70)=checksum         !store result
  1800. RETURN
  1801. '
  1802. ' ***********************************************************************
  1803. ' SEND-PATCH SENDS THE ENTIRE 72 BYTE PATCH TO THE PROPER BANK OF THE
  1804. ' YAMAHA BASED ON THE DROP-DOWN MENU SELECTION.
  1805. ' ***********************************************************************
  1806. '
  1807. PROCEDURE send_patch
  1808.   '
  1809.   n=0                    !point to beginning of buffer
  1810.   FOR i=1 TO 72
  1811.     OUT 3,a(n)           !send all 72 data bytes
  1812.     INC n
  1813.   NEXT i
  1814.   '
  1815. RETURN
  1816. '
  1817. ' ***********************************************************************
  1818. ' PATCH-SAVE WILL SAVE THE 64 BYTES OF MIDI PATCH DATA TO A FILE WHICH
  1819. ' IS ATTACHED TO THE SYSTEM ARCHIVE FILE. THIS IS DONE BY ALLOCATING
  1820. ' A 64 BYTE PATCH BUFFER WHERE EACH PARAMETER IN THE SYSTEM ARRAY BUFFER
  1821. ' IS TRANSFERRED TO THE PATCH BUFFER. A FILESELECTOR IS USED TO ENTER
  1822. ' A NAME FOR THE PATCH AND THEN THE LZH ARCHIVER IS SET UP TO MOVE THE
  1823. ' PATCH FILE TO THE SYSTEM ARCHIVE FILE.  THE USER CAN ALSO ENTER A
  1824. ' BRIEF DESCRIPTION OF THE PATCH SOUND VIA ARCHIVE COMMENTING. THE
  1825. ' CHECK-LZH ROUTINE IS CALLED TO MAKE SURE THE APPROPRIATE ARCHIVE FILE
  1826. ' EXISTS IN THE PROPER DIRECTORY.
  1827. ' ***********************************************************************
  1828. '
  1829. PROCEDURE patch_save
  1830.   '
  1831.   n=6                                   !point to 1st data element
  1832.   patch_buffer=MALLOC(64)               !reserve 64 bytes for patch
  1833.   FOR i=1 TO 64                         !clear patch buffer
  1834.     POKE patch_buffer,0
  1835.     INC patch_buffer
  1836.   NEXT i
  1837.   patch_buffer=patch_buffer-64          !reset pointer
  1838.   FOR i=6 TO 69
  1839.     POKE patch_buffer,a(n)              !write MIDI parameters to buffer
  1840.     INC patch_buffer                    !update buffer pointer
  1841.     INC n                               !update data pointer
  1842.   NEXT i
  1843.   patch_buffer=patch_buffer-64          !reset buffer pointer
  1844.   check_lzh(lzh$,patch_file$,not_found) !check for LZH archiver utility
  1845.   IF not_found THEN
  1846.     GOTO end_patch_save                 !skip for file not found
  1847.   ENDIF
  1848.   path$=DIR$(0)
  1849.   FILESELECT path$+"\*.*","",patch_name$    !call file selector
  1850.   IF RIGHT$(patch_name$)="\" OR patch_name$="" THEN
  1851.     GOTO end_patch_save                 !skip for OK or Cancel button
  1852.   ENDIF
  1853.   BSAVE patch_name$,patch_buffer,64     !save to disk
  1854.   CLS
  1855.   HIDEM
  1856.   c$="mc "+patch_file$+" "+patch_name$  !move file with comments
  1857.   a$=CHR$(LEN(c$))+c$+CHR$(0)           !make command line
  1858.   EXEC 0,lzh$,a$,""                     !call lzh archive utility
  1859.   SHOWM
  1860.   VOID MFREE(patch_buffer)              !free buffer area
  1861.   ' ***********************************************************************
  1862.   ' Export Selection
  1863.   ' ***********************************************************************
  1864.   ALERT 2,"Export to SYX?",1,"yes|no",b
  1865.   SELECT b
  1866.   CASE 1
  1867.     n=0                                   !point to beginning of buffer
  1868.     patch_buffer=MALLOC(72)               !reserve 72 bytes for export
  1869.     FOR i=1 TO 72                         !clear patch buffer
  1870.       POKE patch_buffer,0
  1871.       INC patch_buffer
  1872.     NEXT i
  1873.     patch_buffer=patch_buffer-72          !reset pointer
  1874.     FOR i=1 TO 72
  1875.       POKE patch_buffer,a(n)              !write MIDI parameters to buffer
  1876.       INC patch_buffer                    !update buffer pointer
  1877.       INC n                               !update data pointer
  1878.     NEXT i
  1879.     patch_buffer=patch_buffer-72          !reset buffer pointer
  1880.     BSAVE patch_name$+".SYX",patch_buffer,72     !save to disk
  1881.   CASE 2
  1882.   ENDSELECT
  1883.   '
  1884.   end_patch_save:
  1885.   VOID MFREE(patch_buffer)              !free buffer area
  1886.   DEFMOUSE 3                            !reset mouse cursor to pointing hand
  1887. RETURN
  1888. '
  1889. ' ***********************************************************************
  1890. ' PATCH-LOAD WILL LOAD A PATCH FROM THE SYSTEM ARCHIVE FILE INTO THE
  1891. ' SYSTEM ARRAY BY
  1892. ' ALLOWING THE USER TO ENTER THE PATCH FILE VIA THE FILE SELECTOR.
  1893. ' THE SELECTED FILE IS EXTRACTED AND TRANSFERRED TO THE SYSTEM ARRAY AND
  1894. ' DELETED FROM DISK.  THE SYSTEM ARRAY IS THEN PROCESSED VIA PROCESS-DATA.
  1895. ' ***********************************************************************
  1896. '
  1897. PROCEDURE patch_load
  1898.   '
  1899.   n=6                                   !point to 1st data element
  1900.   patch_buffer=MALLOC(64)               !reserve 64 bytes for patch
  1901.   FOR i=1 TO 64                         !clear patch buffer
  1902.     POKE patch_buffer,0
  1903.     INC patch_buffer
  1904.   NEXT i
  1905.   patch_buffer=patch_buffer-64          !reset pointer
  1906.   CLS
  1907.   HIDEM
  1908.   check_lzh(lzh$,patch_file$,not_found) !check for LZH archive utility
  1909.   IF not_found THEN
  1910.     GOTO end_patch_load                 !skip for file not found
  1911.   ENDIF
  1912.   do_lzh:
  1913.   path$=DIR$(0)
  1914.   get.path(oldpath$)                    !get current drive and path
  1915.   FILESELECT path$+"\*.*","",patch_name$    !call file selector"
  1916.   IF RIGHT$(patch_name$)="\" OR patch_name$="" THEN
  1917.     GOTO end_patch_load                 !skip for OK or Cancel button
  1918.   ENDIF
  1919.   c$="x "+patch_file$+" "+patch_name$   !get file to extract
  1920.   a$=CHR$(LEN(c$))+c$+CHR$(0)           !make command line
  1921.   EXEC 0,lzh$,a$,""                     !call LZH archive utility
  1922.   SHOWM
  1923.   IF NOT EXIST(patch_name$)             !check for user error
  1924.     CLS
  1925.     PRINT AT(1,1);"Error: File Doesn't exist!!!"
  1926.     GOTO do_lzh
  1927.   ENDIF
  1928.   BLOAD patch_name$,patch_buffer        !load patch from disk
  1929.   LET loaded=TRUE
  1930.   FOR i=1 TO 64
  1931.     a(n)=PEEK(patch_buffer)             !write MIDI parameters to buffer
  1932.     INC patch_buffer                    !update buffer pointer
  1933.     INC n                               !update data pointer
  1934.   NEXT i
  1935.   patch_buffer=patch_buffer-64          !reset buffer pointer
  1936.   n=6                                   !point to 1st data element
  1937.   IF HEX$(a(n))="F0"
  1938.     PRINT AT(20,15);"FILE ERROR! - Use Import Selection for .SYX files"
  1939.     PRINT AT(20,17);"<Press Left mouse to continue...>"
  1940.     DO
  1941.     LOOP UNTIL MOUSEK=1
  1942.     GOTO end_patch_load
  1943.   ENDIF
  1944.   get.path(newpath$)                    !see if path has changed
  1945.   IF newpath$=oldpath$
  1946.     KILL patch_name$                    !delete patch file from disk
  1947.   ENDIF
  1948.   process_data                          !process all bytes to GFA parameters
  1949.   '
  1950.   end_patch_load:
  1951.   VOID MFREE(patch_buffer)              !free buffer area
  1952.   DEFMOUSE 3                            !reset mouse cursor to pointing hand
  1953.   '
  1954. RETURN
  1955. '
  1956. PROCEDURE get.path(VAR default.path$)
  1957.   LOCAL default.drive,default.drive$
  1958.   CLR default.path$
  1959.   default.drive=GEMDOS(&H19)
  1960.   default.drive$=CHR$(default.drive+65)
  1961.   default.path$=DIR$(default.drive+1)
  1962.   IF default.path$<>""
  1963.     default.path$=default.drive$+":"+default.path$+"\"
  1964.   ELSE
  1965.     default.path$=default.drive$+":\"
  1966.   ENDIF
  1967. RETURN
  1968. '
  1969. ' ***********************************************************************
  1970. ' PATCH-DELETE WILL DELETE A PATCH FROM THE SYSTEM ARCHIVE FILE USING
  1971. ' THE SAME METHODS AS LOADING AND SAVING.
  1972. ' ***********************************************************************
  1973. '
  1974. PROCEDURE patch_delete
  1975.   '
  1976.   CLS
  1977.   HIDEM
  1978.   check_lzh(lzh$,patch_file$,not_found) !check for LZH archive utility
  1979.   IF not_found THEN
  1980.     GOTO end_patch_delete               !skip for file not found
  1981.   ENDIF
  1982.   path$=DIR$(0)
  1983.   FILESELECT path$+"\*.*","",patch_name$    !call file selector
  1984.   IF RIGHT$(patch_name$)="\" OR patch_name$="" THEN
  1985.     GOTO end_patch_delete               !skip for OK or Cancel button
  1986.   ENDIF
  1987.   c$="d "+patch_file$+" "+patch_name$   ! get file to delete
  1988.   a$=CHR$(LEN(c$))+c$+CHR$(0)           !make command line
  1989.   lzh$="lha.ttp"                        !path for LZH
  1990.   EXEC 0,lzh$,a$,""                     !call LZH archive utility
  1991.   deleted=TRUE
  1992.   SHOWM
  1993.   '
  1994.   end_patch_delete:
  1995.   DEFMOUSE 3                            !reset mouse cursor to pointing hand
  1996.   '
  1997. RETURN
  1998. '
  1999. ' ***********************************************************************
  2000. ' VERBOSE WILL PERFORM A VERBOSE DIRECTORY ON THE SYSTEM ARCHIVE FILE
  2001. ' WHERE EACH PATCH WILL BE DISPLAYED ALONG WITH ITS DATE/TIMESTAMP AND
  2002. ' ALL COMMENT DESCRIPTIONS.
  2003. ' ***********************************************************************
  2004. '
  2005. PROCEDURE verbose
  2006.   '
  2007.   CLS
  2008.   HIDEM                                 !Hide the mouse
  2009.   check_lzh(lzh$,patch_file$,not_found) !check for LZH archive utility
  2010.   IF not_found THEN
  2011.     GOTO end_verbose                    !skip for file not found
  2012.   ENDIF
  2013.   c$="vch "+patch_file$                 !lha verbose listing w/comments
  2014.   a$=CHR$(LEN(c$))+c$+CHR$(0)           !make command line
  2015.   EXEC 0,lzh$,a$,""                     !call LZH archive utility
  2016.   '
  2017.   end_verbose:
  2018.   SHOWM                                 !show the mouse as a pointing hand
  2019.   DEFMOUSE 3
  2020. RETURN
  2021. '
  2022. ' ***********************************************************************
  2023. ' CHECK-LZH WILL MAKE SURE THAT THE BOTH THE LHA.TTP ARCHIVE UTILITY AS
  2024. ' WELL AS THE PATCHES.LZH SYSTEM ARCHIVE FILE EXISTS IN THE PROPER
  2025. ' DIRECTORY.  ALERT BOXES ARE IMPLEMENTED IN THE CASE WHERE THESE FILES
  2026. ' DON'T EXIST AND ALL SYSTEM FILE OPERATIONS ARE BYPASSED IN THIS INSTANCE.
  2027. ' ***********************************************************************
  2028. '
  2029. PROCEDURE check_lzh(VAR lzh$,patch_file$,not_found)
  2030.   '
  2031.   not_found=FALSE                       !clear flag
  2032.   path$=DIR$(0)                         !get current path
  2033.   lzh_file$="lha.ttp"
  2034.   x=FSFIRST(lzh_file$,0)                !make sure LHA.TTP exists
  2035.   IF x<>0 THEN
  2036.     ALERT 1,"LHA.TTP was not found",1,"OK",b
  2037.     not_found=TRUE                      !set flag
  2038.   ELSE
  2039.     lzh$=lzh_file$
  2040.   ENDIF
  2041.   patch_file$="patches.lzh"
  2042.   y=FSFIRST(patch_file$,0)              !make sure PATCHES.LZH exists
  2043.   IF y<>0 THEN
  2044.     ALERT 1,"The Archive, PATCHES.LZH|was not found",1,"OK",b
  2045.     not_found=TRUE                      !set flag
  2046.   ENDIF
  2047.   '
  2048. RETURN
  2049. '
  2050. ' ***********************************************************************
  2051. ' CHECK-VIEWMODE WILL DISPLAY THE SYSTEM ARRAY IN EITHER HEX BYTES OR
  2052. ' MIDI PARAMETERS DEPENDING UPON THE VIEWFLAG SETTING.
  2053. ' ***********************************************************************
  2054. '
  2055. PROCEDURE check_viewmode
  2056.   '
  2057.   IF flag THEN
  2058.     view_bytes
  2059.   ELSE
  2060.     view_parameters
  2061.   ENDIF
  2062.   '
  2063. RETURN
  2064. '
  2065. ' ***********************************************************************
  2066. ' VIEW-PARAMETERS WILL FORMAT THE SCREEN TO DISPLAY ALL SYSTEM PARAMETER
  2067. ' VALUES BY CONVERTING THE PARAMETER VALUE TO A STRING VIA STR$.  BOTH
  2068. ' COLOR AND MONOCHROME SCREEN DISPLAYS ARE SUPPORTED (WITH A SLIGHT
  2069. ' DIFFERENCE IN PRESENTATION).  ANY MOUSE MOVEMENT WILL EXIT THE SCREEN
  2070. ' DISPLAY AND RETURN TO THE GEM MENU.
  2071. ' ***********************************************************************
  2072. '
  2073. PROCEDURE view_parameters
  2074.   '
  2075.   CLS
  2076.   MENU m$()
  2077.   a=MOUSEX
  2078.   b=MOUSEY
  2079.   IF rez=1 THEN
  2080.     DEFTEXT 3,9,0,6
  2081.     TEXT 20,20,"MODULATION"
  2082.   ELSE
  2083.     DEFTEXT 2,1,0,10
  2084.     TEXT 20,50,"MODULATION"
  2085.   ENDIF
  2086.   IF rez=1 THEN
  2087.     DEFTEXT 2,9,0,6
  2088.     TEXT 0,35,"LEVELING:"
  2089.   ENDIF
  2090.   PRINT AT(1,7);"Modulation Level"
  2091.   PRINT AT(19,7);"= ";STR$(mod_level)
  2092.   PRINT AT(1,8);"Total Level"
  2093.   PRINT AT(19,8);"= ";STR$(total_level)
  2094.   PRINT AT(1,9);"Feedback Level"
  2095.   PRINT AT(19,9);"= ";STR$(fb_level)
  2096.   IF rez=1 THEN
  2097.     TEXT 0,86,"AM:"
  2098.   ENDIF
  2099.   PRINT AT(1,13);"AM Sensitivity"
  2100.   PRINT AT(19,13);"= ";STR$(ams)
  2101.   IF rez=1 THEN
  2102.     TEXT 0,120,"FM:"
  2103.   ENDIF
  2104.   PRINT AT(1,17);"FM(Vibrato) Enable"
  2105.   IF fm_en=0
  2106.     fm_en$="OFF"
  2107.   ENDIF
  2108.   PRINT AT(19,17);"= ";fm_en$
  2109.   PRINT AT(1,18);"FM Sensitivity"
  2110.   PRINT AT(19,18);"= ";STR$(pms)
  2111.   PRINT AT(1,19);"FM Delay Time"
  2112.   PRINT AT(19,19);"= ";STR$(fm_delay)
  2113.   PRINT AT(1,20);"Sustain Enable"
  2114.   IF sus_en=0
  2115.     sus_en$="OFF"
  2116.   ENDIF
  2117.   PRINT AT(19,20);"= ";sus_en$
  2118.   IF rez=1 THEN
  2119.     DEFTEXT 3,9,0,6
  2120.     TEXT 220,20,"MODULATOR"
  2121.   ELSE
  2122.     DEFTEXT 2,1,0,10
  2123.     TEXT 225,50,"MODULATOR"
  2124.   ENDIF
  2125.   DEFTEXT 2,5,0,6
  2126.   SELECT wavform_mod_last
  2127.   CASE 0
  2128.     IF rez=1 THEN
  2129.       TEXT 190,35,"WAVEFORM = SINE WAVE"
  2130.     ELSE
  2131.       TEXT 190,80,"WAVEFORM = SINE WAVE"
  2132.     ENDIF
  2133.   CASE 1
  2134.     IF rez=1 THEN
  2135.       TEXT 190,35,"WAVEFORM = SQUARE WAVE"
  2136.     ELSE
  2137.       TEXT 190,80,"WAVEFORM = SQUARE WAVE"
  2138.     ENDIF
  2139.   CASE 2
  2140.     IF rez=1 THEN
  2141.       TEXT 190,35,"WAVEFORM = HALF SINE WAVE"
  2142.     ELSE
  2143.       TEXT 190,80,"WAVEFORM = HALF SINE WAVE"
  2144.     ENDIF
  2145.   CASE 3
  2146.     IF rez=1 THEN
  2147.       TEXT 190,35,"WAVEFORM = HALF SQUARE WAVE"
  2148.     ELSE
  2149.       TEXT 190,80,"WAVEFORM = HALF SQUARE WAVE"
  2150.     ENDIF
  2151.   ENDSELECT
  2152.   IF rez=1 THEN
  2153.     DEFTEXT 2,9,0,6
  2154.     TEXT 190,45,"TUNING:"
  2155.   ENDIF
  2156.   PRINT AT(25,7);"Fine Detune"
  2157.   PRINT AT(47,7);"= ";STR$(dt_mod_last)
  2158.   IF cdt_mod_last=0
  2159.     cdt_mod$="OFF"
  2160.   ELSE
  2161.     cdt_mod$="ON"
  2162.   ENDIF
  2163.   PRINT AT(25,8);"Course Detune"
  2164.   PRINT AT(47,8);"= ";cdt_mod$
  2165.   IF rez=1 THEN
  2166.     TEXT 190,70,"FREQUENCY:"
  2167.   ENDIF
  2168.   PRINT AT(25,10);"Frequency Multiplier"
  2169.   PRINT AT(47,10);"= ";STR$(freq_mod_last)
  2170.   IF rez=1 THEN
  2171.     TEXT 190,86,"LKS/RKS:"
  2172.   ENDIF
  2173.   PRINT AT(25,12);"Level Key Scale Hi"
  2174.   PRINT AT(47,12);"= ";STR$(lks_hi_mod_last)
  2175.   PRINT AT(25,13);"Level Key Scale Lo"
  2176.   PRINT AT(47,13);"= ";STR$(lks_lo_mod_last)
  2177.   PRINT AT(25,14);"Rate Key Scale"
  2178.   PRINT AT(47,14);"= ";STR$(rks_mod_last)
  2179.   IF rez=1 THEN
  2180.     TEXT 190,120,"ENVELOPE PARAMETERS:"
  2181.   ENDIF
  2182.   PRINT AT(25,17);"Attack Rate"
  2183.   PRINT AT(47,17);"= ";STR$(atk_mod_last)
  2184.   PRINT AT(25,18);"Decay 1 Rate"
  2185.   PRINT AT(47,18);"= ";STR$(d1r_mod_last)
  2186.   PRINT AT(25,19);"Decay 1 Level"
  2187.   PRINT AT(47,19);"= ";STR$(d1l_mod_last)
  2188.   PRINT AT(25,20);"Decay 2 Rate"
  2189.   PRINT AT(47,20);"= ";STR$(d2r_mod_last)
  2190.   PRINT AT(25,21);"Release Rate"
  2191.   PRINT AT(47,21);"= ";STR$(rr_mod_last)
  2192.   PRINT AT(25,22);"Sustain Release Rate"
  2193.   PRINT AT(47,22);"= ";STR$(srr_mod_last)
  2194.   PRINT AT(25,23);"AM Enable"
  2195.   IF am_en_mod_last=0
  2196.     am_en_mod$="OFF"
  2197.   ELSE
  2198.     am_en_mod$="ON"
  2199.   ENDIF
  2200.   PRINT AT(47,23);"= ";am_en_mod$
  2201.   IF rez=1 THEN
  2202.     DEFTEXT 3,9,0,6
  2203.     TEXT 475,20,"CARRIER"
  2204.   ELSE
  2205.     DEFTEXT 2,1,0,10
  2206.     TEXT 475,50,"CARRIER"
  2207.   ENDIF
  2208.   DEFTEXT 2,5,0,6
  2209.   SELECT wavform_car_last
  2210.   CASE 0
  2211.     IF rez=1 THEN
  2212.       TEXT 420,35,"WAVEFORM = SINE WAVE"
  2213.     ELSE
  2214.       TEXT 420,80,"WAVEFORM = SINE WAVE"
  2215.     ENDIF
  2216.   CASE 1
  2217.     IF rez=1 THEN
  2218.       TEXT 420,35,"WAVEFORM = SQUARE WAVE"
  2219.     ELSE
  2220.       TEXT 420,80,"WAVEFORM = SQUARE WAVE"
  2221.     ENDIF
  2222.   CASE 2
  2223.     IF rez=1 THEN
  2224.       TEXT 420,35,"WAVEFORM = HALF SINE WAVE"
  2225.     ELSE
  2226.       TEXT 420,80,"WAVEFORM = HALF SINE WAVE"
  2227.     ENDIF
  2228.   CASE 3
  2229.     IF rez=1 THEN
  2230.       TEXT 420,35,"WAVEFORM = HALF SQUARE WAVE"
  2231.     ELSE
  2232.       TEXT 420,80,"WAVEFORM = HALF SQUARE WAVE"
  2233.     ENDIF
  2234.   ENDSELECT
  2235.   IF rez=1 THEN
  2236.     DEFTEXT 2,9,0,6
  2237.     TEXT 420,45,"TUNING:"
  2238.   ENDIF
  2239.   PRINT AT(54,7);"Fine Detune"
  2240.   PRINT AT(76,7);"= ";STR$(dt_car_last)
  2241.   PRINT AT(54,8);"Course Detune"
  2242.   IF cdt_car_last=0
  2243.     cdt_car$="OFF"
  2244.   ELSE
  2245.     cdt_car$="ON"
  2246.   ENDIF
  2247.   PRINT AT(76,8);"= ";cdt_car$
  2248.   IF rez=1 THEN
  2249.     TEXT 420,70,"FREQUENCY:"
  2250.   ENDIF
  2251.   PRINT AT(54,10);"Frequency Multiplier"
  2252.   PRINT AT(76,10);"= ";STR$(freq_car_last)
  2253.   IF rez=1 THEN
  2254.     TEXT 420,86,"LKS/RKS:"
  2255.   ENDIF
  2256.   PRINT AT(54,12);"Level Key Scale Hi"
  2257.   PRINT AT(76,12);"= ";STR$(lks_hi_car_last)
  2258.   PRINT AT(54,13);"Level Key Scale Lo"
  2259.   PRINT AT(76,13);"= ";STR$(lks_lo_car_last)
  2260.   PRINT AT(54,14);"Rate Key Scale"
  2261.   PRINT AT(76,14);"= ";STR$(rks_car_last)
  2262.   IF rez=1 THEN
  2263.     TEXT 420,120,"ENVELOPE PARAMETERS:"
  2264.   ENDIF
  2265.   PRINT AT(54,17);"Attack Rate"
  2266.   PRINT AT(76,17);"= ";STR$(atk_car_last)
  2267.   PRINT AT(54,18);"Decay 1 Rate"
  2268.   PRINT AT(76,18);"= ";STR$(d1r_car_last)
  2269.   PRINT AT(54,19);"Decay 1 Level"
  2270.   PRINT AT(76,19);"= ";STR$(d1l_car_last)
  2271.   PRINT AT(54,20);"Decay 2 Rate"
  2272.   PRINT AT(76,20);"= ";STR$(d2r_car_last)
  2273.   PRINT AT(54,21);"Release Rate"
  2274.   PRINT AT(76,21);"= ";STR$(rr_car_last)
  2275.   PRINT AT(54,22);"Sustain Release Rate"
  2276.   PRINT AT(76,22);"= ";STR$(srr_car_last)
  2277.   PRINT AT(54,23);"AM Enable"
  2278.   IF am_en_car_last=0
  2279.     am_en_car$="OFF"
  2280.   ELSE
  2281.     am_en_car$="ON"
  2282.   ENDIF
  2283.   PRINT AT(76,23);"= ";am_en_car$
  2284.   DEFTEXT 1,0,0,10            !define text for larger screen font
  2285.   '
  2286. RETURN
  2287. '
  2288. ' ***********************************************************************
  2289. ' PROCESS-DATA WILL PROCESS ALL MIDI SYSTEM EXCLUSIVE DATA EITHER IF IT
  2290. ' WAS RECEIVED FROM THE YAMAHA INSTRUMENT OR LOADED FROM DISK.  EACH
  2291. ' DATA PARAMETER IS TRANSLATED INTO ITS PROPER DECIMAL FORMAT VIA BIT
  2292. ' MANIPULATION OF EACH ELEMENT IN THE SYSTEM ARRAY.  THE CLEANUP ROUTINE
  2293. ' IS CALLED AT THE END IN ORDER TO ENSURE DATA INTEGRITY WITH ALL DATA
  2294. ' BYTES THAT HAVE COMBINATIONS OF PATCH PARAMETERS.
  2295. ' ***********************************************************************
  2296. '
  2297. PROCEDURE process_data
  2298.   '
  2299.   n=6                              !point to 1st data element in system array
  2300.   signflag=BTST(a(n),3)            !check sign bit of fine detune mod
  2301.   IF NOT signflag THEN             !if 0, just store value
  2302.     dt_mod_last=a(n)
  2303.   ELSE
  2304.     dt_mod_last=-(BCLR(a(n),3))    !else, fine detune mod is negative
  2305.   ENDIF
  2306.   '
  2307.   freq_mod_last=a(n+1)             !store frequency mod value
  2308.   '
  2309.   signflag=BTST(a(n+2),3)          !check sign bit of fine detune car
  2310.   IF NOT signflag THEN             !if 0, just store value
  2311.     dt_car_last=a(n+2)
  2312.   ELSE
  2313.     dt_car_last=-(BCLR(a(n+2),3))  !else, fine detune car is negative
  2314.   ENDIF
  2315.   '
  2316.   freq_car_last=a(n+3)             !store frequency car value
  2317.   '
  2318.   IF a(n+4)=7 AND a(n+5)=15 THEN   !check for null mod level
  2319.     mod_level=0
  2320.   ELSE
  2321.     mod_level=99-(SHL(a(n+4),4)+a(n+5)) !mod level is 99 -[16*MSB+LSB]
  2322.   ENDIF
  2323.   IF a(n+6)=7 AND a(n+7)=15 THEN   !check for null total level
  2324.     total_level=0
  2325.   ELSE
  2326.     total_level=99-(SHL(a(n+6),4)+a(n+7)) !total level is 99 -[16*MSB+LSB]
  2327.   ENDIF
  2328.   '
  2329.   lks_hi_mod_last=a(n+8)           !store lks hi mod value
  2330.   lks_lo_mod_last=a(n+9)           !store lks lo mod value
  2331.   '
  2332.   lks_hi_car_last=a(n+10)          !store lks hi car value
  2333.   lks_lo_car_last=a(n+11)          !store lks lo car value
  2334.   '
  2335.   ' ***********************************************************************
  2336.   ' RKS = N/4 WITH MSB OF ATK MASKED OFF
  2337.   ' ATK = MSB [N*16 WITH RKS MASKED OFF] + LSB
  2338.   ' ***********************************************************************
  2339.   rks_mod_last=SHR(a(n+12) AND &HC,2)
  2340.   atk_mod_last=SHL(a(n+12) AND &H3,4)+a(n+13)
  2341.   '
  2342.   rks_car_last=SHR(a(n+14) AND &HC,2)
  2343.   atk_car_last=SHL(a(n+14) AND &H3,4)+a(n+15)
  2344.   '
  2345.   ' ***********************************************************************
  2346.   ' AM_EN = N/8 WITH BOTH CDT AND MSB OF D1R MASKED OFF
  2347.   ' CDT = N/4 WITH BOTH AM_EN AND MSB OF D1R MASKED OFF
  2348.   ' D1R = MSB [N*16 WITH AM_EN AND CDT MASKED OFF] + LSB
  2349.   ' ***********************************************************************
  2350.   am_en_mod_last=SHR(a(n+16) AND &H8,3)
  2351.   cdt_mod_last=SHR(a(n+16) AND &H4,2)
  2352.   d1r_mod_last=SHL(a(n+16) AND &H3,4)+a(n+17)
  2353.   '
  2354.   am_en_car_last=SHR(a(n+18) AND &H8,3)
  2355.   cdt_car_last=SHR(a(n+18) AND &H4,2)
  2356.   d1r_car_last=SHL(a(n+18) AND &H3,4)+a(n+19)
  2357.   '
  2358.   ' ***********************************************************************
  2359.   ' WAVEFORM = N/4 WITH MSB OF D2R MASKED OFF
  2360.   ' D2R = MSB [N*16 WITH WAVEFORM MASKED OFF] + LSB
  2361.   ' ***********************************************************************
  2362.   wavform_mod_last=SHR(a(n+20) AND &HC,2)
  2363.   d2r_mod_last=SHL(a(n+20) AND &H3,4)+a(n+21)
  2364.   '
  2365.   wavform_car_last=SHR(a(n+22) AND &HC,2)
  2366.   d2r_car_last=SHL(a(n+22) AND &H3,4)+a(n+23)
  2367.   '
  2368.   d1l_mod_last=a(n+24)                  !store d1l mod value
  2369.   rr_mod_last=a(n+25)                   !store rr mod value
  2370.   d1l_car_last=a(n+26)                  !store d1l car value
  2371.   rr_car_last=a(n+27)                   !store rr car value
  2372.   '
  2373.   ' ***********************************************************************
  2374.   ' FB LEVEL = MSB [N*2 WITH LAST BIT MASKED OFF]
  2375.   '          + LSB [N/8 WITH LAST 3 BITS MASKED OFF]
  2376.   ' ***********************************************************************
  2377.   fb_level=(SHL(a(n+28),1) AND &H7)+(SHR(a(n+29),3) AND &H1)
  2378.   '
  2379.   pms=a(n+30) AND &H7   !store pms value and mask off don't cares
  2380.   ams=a(n+31) AND &H3   !store ams value and mask off don't cares
  2381.   '
  2382.   srr_mod_last=a(n+39)  !store srr mod value
  2383.   srr_car_last=a(n+41)  !store srr car value
  2384.   '
  2385.   ' ***********************************************************************
  2386.   ' FM DELAY = MSB [N*16] + LSB
  2387.   ' FM EN = N/8 WITH SUS EN MASKED OFF
  2388.   ' SUS EN = N/4 WITH FM EN MASKED OFF
  2389.   ' ***********************************************************************
  2390.   fm_delay=SHL(a(n+42),4)+a(n+43)
  2391.   fm_en=SHR(a(n+46),3) AND &H1
  2392.   IF fm_en=0
  2393.     fm_en$="OFF"
  2394.   ELSE
  2395.     fm_en$="ON"
  2396.   ENDIF
  2397.   sus_en=SHR(a(n+46),2) AND &H1
  2398.   IF sus_en=0
  2399.     sus_en$="OFF"
  2400.   ELSE
  2401.     sus_en$="ON"
  2402.   ENDIF
  2403.   IF received                   ! Save screen if receiving
  2404.     SGET screen$
  2405.   ENDIF
  2406.   cleanup
  2407.   IF received                   ! Screen indicates that bank was received
  2408.     SPUT screen$
  2409.   ENDIF
  2410.   '
  2411. RETURN
  2412. '
  2413. ' ***********************************************************************
  2414. ' CLEANUP MAKES SURE THAT ALL SYSTEM DATA BYTES THAT HAVE COMBINATIONS
  2415. ' OF MIDI PARAMETERS ARE PROPERLY UPDATED WITH THEIR LAST VALUES BY
  2416. ' CALLING THOSE RELEVANT ROUTINES WHICH SET THE LAST VALUE.  THIS WILL
  2417. ' OCCUR WHEN LOADING FROM DISK OR RECEIVING FROM THE YAMAHA INSTRUMENT.
  2418. ' ***********************************************************************
  2419. '
  2420. PROCEDURE cleanup
  2421.   '
  2422.   ' ***********************************************************************
  2423.   ' UPDATE BYTES 12,14  WITH LAST RKS VALUES
  2424.   ' ***********************************************************************
  2425.   '
  2426.   lks_rks_modulator(rks_mod,atk_mod)
  2427.   lks_rks_carrier(rks_car,atk_car)
  2428.   '
  2429.   ' ***********************************************************************
  2430.   ' UPDATE BYTES 16,18  WITH LAST CDT VALUES
  2431.   ' ***********************************************************************
  2432.   '
  2433.   tune_modulator(cdt_mod,d1r_mod,am_en_mod)
  2434.   tune_carrier(cdt_car,d1r_car,am_en_car)
  2435.   '
  2436.   ' ***********************************************************************
  2437.   ' UPDATE BYTES 20,22  WITH LAST WAVEFORM VALUES
  2438.   ' ***********************************************************************
  2439.   '
  2440.   wave_mod(wavform_mod,d2r_mod)
  2441.   wave_car(wavform_car,d2r_car)
  2442.   '
  2443.   ' ***********************************************************************
  2444.   ' UPDATE BYTES 12,14,16,18,20,22  WITH LAST ATK,AM_EN,D1R,D2R VALUES
  2445.   ' ***********************************************************************
  2446.   '
  2447.   envelope_mod(rks_mod,atk_mod,d1r_mod,am_en_mod,cdt_mod,d2r_mod,wavform_mod)
  2448.   envelope_car(rks_car,atk_car,d1r_car,am_en_car,cdt_car,d2r_car,wavform_car)
  2449.   '
  2450.   LET loaded=FALSE              !reset flag
  2451.   '
  2452. RETURN
  2453. '
  2454. ' ***********************************************************************
  2455. ' INIT-BUFFER INITIALIZES THE 72 BYTE SYSTEM MIDI ARRAY USED TO HOLD
  2456. ' ALL PATCH PARAMETERS.
  2457. ' ***********************************************************************
  2458. '
  2459. PROCEDURE init_buffer
  2460.   '
  2461.   n=71                        ! set array size
  2462.   ERASE a()
  2463.   DIM a(71)
  2464.   a(0)=240                    ! define MIDI Status byte (&HF0)
  2465.   a(1)=67                     ! define MIDI Instrument ID for Yamaha (&H43)
  2466.   a(2)=118                    ! define MIDI Class byte (&H76)
  2467.   a(3)=0                      ! define MIDI Format # (&H00)
  2468.   a(4)=0                      ! define MSB of Bank # (always 0)
  2469.   a(71)=247                   ! define MIDI EOX tail byte (&HF7)
  2470.   a(10)=7                     ! initialize leveling bytes to 0 leveling
  2471.   a(11)=15
  2472.   a(12)=7
  2473.   a(13)=15
  2474.   '
  2475. RETURN
  2476. '
  2477. ' ***********************************************************************
  2478. ' INIT-PARAMETERS IS CALLED ONCE AT THE BEGINNING OF PROGRAM TO INITIALIZE
  2479. ' ALL SYSEX MIDI PARAMETERS.
  2480. ' ***********************************************************************
  2481. '
  2482. PROCEDURE init_parameters
  2483.   '
  2484.   CLR mod_level               ! Clear all MIDI Sysex parameters
  2485.   CLR total_level
  2486.   CLR fb_level
  2487.   CLR ams
  2488.   CLR fm_en
  2489.   CLR pms
  2490.   CLR fm_delay
  2491.   CLR sus_en
  2492.   CLR wavform_mod_last
  2493.   CLR dt_mod_last
  2494.   CLR cdt_mod_last
  2495.   CLR freq_mod_last
  2496.   CLR lks_hi_mod_last
  2497.   CLR lks_lo_mod_last
  2498.   CLR rks_mod_last
  2499.   CLR atk_mod_last
  2500.   CLR d1r_mod_last
  2501.   CLR d1l_mod_last
  2502.   CLR d2r_mod_last
  2503.   CLR rr_mod_last
  2504.   CLR srr_mod_last
  2505.   CLR am_en_mod_last
  2506.   CLR wavform_car_last
  2507.   CLR dt_car_last
  2508.   CLR cdt_car_last
  2509.   CLR freq_car_last
  2510.   CLR lks_hi_car_last
  2511.   CLR lks_lo_car_last
  2512.   CLR rks_car_last
  2513.   CLR atk_car_last
  2514.   CLR d1r_car_last
  2515.   CLR d1l_car_last
  2516.   CLR d2r_car_last
  2517.   CLR rr_car_last
  2518.   CLR srr_car_last
  2519.   CLR am_en_car_last
  2520.   '
  2521. RETURN
  2522. '
  2523. ' ***********************************************************************
  2524. ' VIEW-BYTES IS USED TO DISPLAY IN HEXADECIMAL ALL 64 CURRENT MIDI SYSEX
  2525. ' PARAMETERS WHEN IT IS SELECTED FROM THE DROP-DOWN MENU.  IF THE
  2526. ' BUFFER WAS LOADED FROM DISK, THE FILENAME WILL ALSO BE SHOWN.  IF THE
  2527. ' BUFFER WAS RECEIVED FROM THE YAMAHA OR EDITED FROM SCRATCH, THE USER
  2528. ' IS INFORMED THAT THE BUFFER IS CURRENTLY UNNAMED.
  2529. ' ***********************************************************************
  2530. '
  2531. PROCEDURE view_bytes
  2532.   '
  2533.   CLS                         ! Clear Screen
  2534.   MENU m$()                   ! Display GEM menu
  2535.   lx=25                       ! Implement box routine
  2536.   ty=60
  2537.   rx=590
  2538.   by=110
  2539.   DEFFILL 0,2,8
  2540.   IF rez=2
  2541.     by=by+by-ty
  2542.     DEFTEXT 1,0,0,13
  2543.   ENDIF
  2544.   PBOX lx,ty,rx,by
  2545.   DEFLINE 1,3
  2546.   BOX lx,ty,rx,by
  2547.   DEFLINE 1,1
  2548.   BOX lx+8,ty+2,rx-8,by-2
  2549.   n=6                         ! Point to first element of MIDI SYSEX data
  2550.   x=8                         ! position patch table
  2551.   IF rez=1                    ! check screen resolution
  2552.     y=10
  2553.   ELSE
  2554.     y=6
  2555.   ENDIF
  2556.   LOCATE x,y
  2557.   FOR i=1 TO 4
  2558.     FOR j=1 TO 16             ! Display 4 rows by 16 columns
  2559.       byte$=HEX$(a(n))        ! Get value in hex
  2560.       INC n                   ! point to next data array element
  2561.       EXIT IF n=71            ! Display a total of 64 data bytes
  2562.       PRINT "0";byte$;"  ";   ! display MIDI parameter in hex (byte form)
  2563.     NEXT j
  2564.     PRINT
  2565.     INC y
  2566.     LOCATE x,y                ! reposition cursor
  2567.   NEXT i
  2568.   IF patch_name$="" OR receiving OR deleted THEN
  2569.     PRINT AT(27,17);"Buffer = Unnamed Patch";
  2570.   ELSE
  2571.     PRINT AT(27,17);"Buffer = ";patch_name$;
  2572.   ENDIF
  2573.   receiving=FALSE             ! reset flag
  2574.   deleted=FALSE               ! reset flag
  2575.   patch_name$=""              ! clear file name
  2576.   DEFTEXT 1,0,0,10            !define text for larger screen font
  2577.   '
  2578. RETURN
  2579. '
  2580. ' ***********************************************************************
  2581. ' THE NEXT SET OF ROUTINES PERTAIN TO EDITING ALL SYSTEM EXCLUSIVE
  2582. ' PATCH PARAMETERS AND ARE SELECTED VIA THE DROP-DOWN MENUS.  FOR THOSE
  2583. ' ITEMS THAT ARE PART OF THE MODULATOR/CARRIER SECTIONS, IN GENERAL,
  2584. ' THE CURRENT VALUE IS SET TO THE LAST VALUE (EITHER LOADED FROM DISK,
  2585. ' RECEIVED FROM YAMAHA INSTRUMENT, OR PREVIOUSLY SELECTED) AND A ROUTINE
  2586. ' TO OBTAIN THE PARAMETER VALUES IN DECIMAL VIA THE MOUSE IS CALLED.
  2587. ' ONCE THE VALUE IS STORED, THE LAST VALUE IS NOW THE CURRENT VALUE FOR
  2588. ' THE NEXT TIME THRU.  THE SYSTEM MIDI ARRAY IS UPDATED VIA SPECIFIC
  2589. ' BIT MANIPULATION FOR EACH PARAMETER.  FOR BOTH LEVELING, AM/FM
  2590. ' PARAMETERS, NO EXTRA ROUTINE IS CALLED WHICH IS WHY ITS GROUPED INTO
  2591. ' ITS OWN SECTION (NOTE: THESE PARAMETERS EFFECT THE PATCH SOUND AS A
  2592. ' WHOLE RATHER THAN BEING SPLIT INTO THE MODULATOR AND CARRIER.)
  2593. ' ***********************************************************************
  2594. '
  2595. ' ***********************************************************************
  2596. ' TUNE-MODULATOR WILL IMPLEMENT BOTH FINE AND COURSE DE-TUNING OF THE
  2597. ' MODULATOR PART OF THE SOUND PATCH.  THE FINE DE-TUNE ROUTINE IS CALLED
  2598. ' TO OBTAIN THE DECIMAL VALUE.  IF THE VALUE IS NEGATIVE, THE SIGN BIT
  2599. ' IS SET IN THE SYSTEM MIDI ARRAY ELEMENT.  FOR COURSE DE-TUNING, A BIT
  2600. ' IS LEFT-SHIFTED 2 TIMES AND CHECKED AGAINST THE CURRENT AM EN/D1R(MSB)
  2601. ' VALUES AN STORED IN THE SYSTEM MIDI ARRAY ELEMENT.
  2602. ' ***********************************************************************
  2603. '
  2604. PROCEDURE tune_modulator(VAR cdt_mod,d1r_mod,am_en_mod)
  2605.   '
  2606.   CLS                         ! clear the screen
  2607.   MENU m$()                   ! show GEM menu
  2608.   dt_mod=dt_mod_last          ! get last value for display
  2609.   cdt_mod=cdt_mod_last
  2610.   IF cdt_mod=0
  2611.     cdt_mod$="OFF"
  2612.   ELSE
  2613.     cdt_mod$="ON"
  2614.   ENDIF
  2615.   IF loaded OR received THEN  ! Exit if just updating last values
  2616.     GOTO end_tune_mod
  2617.   ENDIF
  2618.   fine_detune(dt_mod,cdt_mod$) ! calculate new dt parameter
  2619.   n=6                         ! fine detune mod is byte 06
  2620.   IF dt_mod>=0 THEN           ! Sharped tuning case
  2621.     a(n)=dt_mod               ! just store new value
  2622.     dt_mod_last=dt_mod        ! Save value
  2623.   ELSE                        ! Flat tuning case
  2624.     r=ABS(dt_mod)             ! Get absolute value
  2625.     dt_mod_last=dt_mod        ! Save value
  2626.     a(n)=r OR &H8             ! OR value with sign bit
  2627.   ENDIF
  2628.   n=22                        ! course detune mod is 2nd bit of byte 16
  2629.   IF cdt_mod$="OFF"
  2630.     cdt_mod=0
  2631.   ELSE
  2632.     cdt_mod=1
  2633.   ENDIF
  2634.   IF d1r_mod=0 AND am_en_mod=0 THEN
  2635.     a(n)=SHL(cdt_mod,2)       ! cdt_mod:shift left 2x
  2636.   ELSE
  2637.     IF d1r_mod=0 AND am_en_mod<>0 THEN
  2638.       a(n)=(SHL(cdt_mod,2)) OR (SHL(am_en_mod,3))
  2639.     ELSE
  2640.       IF d1r_mod>15 AND am_en_mod<>0 THEN
  2641.         a(n)=(SHL(cdt_mod,2)) OR (SHL(am_en_mod,3)) OR (SHR(d1r_mod,4))
  2642.       ELSE
  2643.         a(n)=(SHL(cdt_mod,2)) OR (SHR(d1r_mod,4)) ! d1r_mod:shift right 4 x
  2644.       ENDIF
  2645.     ENDIF
  2646.   ENDIF
  2647.   cdt_mod_last=cdt_mod        ! Save value
  2648.   '
  2649.   end_tune_mod:
  2650. RETURN
  2651. '
  2652. ' ***********************************************************************
  2653. ' TUNE-CARRIER EFFECTS THE CARRIER PART OF THE SOUND PATCH.  SEE THE
  2654. ' PREVIOUS ROUTINE FOR A DETAILED DESCRIPTION.
  2655. ' ***********************************************************************
  2656. '
  2657. PROCEDURE tune_carrier(VAR cdt_car,d1r_car,am_en_car)
  2658.   '
  2659.   CLS                         ! clear the screen
  2660.   MENU m$()                   ! show GEM menu
  2661.   dt_car=dt_car_last          ! get last value for display
  2662.   cdt_car=cdt_car_last
  2663.   IF cdt_car=0
  2664.     cdt_car$="OFF"
  2665.   ELSE
  2666.     cdt_car$="ON"
  2667.   ENDIF
  2668.   IF loaded OR received THEN  ! Exit if just updating last values
  2669.     GOTO end_tune_car
  2670.   ENDIF
  2671.   fine_detune(dt_car,cdt_car$) ! calculate new dt parameter
  2672.   n=8                         ! fine detune carrier is byte 08
  2673.   IF dt_car>=0 THEN           ! Sharped tuning case
  2674.     a(n)=dt_car               ! store new value
  2675.     dt_car_last=dt_car        ! Save value
  2676.   ELSE                        ! Flat tuning case
  2677.     r=ABS(dt_car)             ! Get absolute value
  2678.     dt_car_last=dt_car        ! Save value
  2679.     a(n)=r OR &H8             ! OR value with sign bit
  2680.   ENDIF
  2681.   n=24                        ! course detune car is 2nd bit of byte 18
  2682.   IF cdt_car$="OFF"
  2683.     cdt_car=0
  2684.   ELSE
  2685.     cdt_car=1
  2686.   ENDIF
  2687.   IF d1r_car=0 AND am_en_car=0 THEN
  2688.     a(n)=SHL(cdt_car,2)       ! cdt_car:shift left 2x
  2689.   ELSE
  2690.     IF d1r_car=0 AND am_en_car<>0 THEN
  2691.       a(n)=(SHL(cdt_car,2)) OR (SHL(am_en_car,3))
  2692.     ELSE
  2693.       IF d1r_car>15 AND am_en_car<>0 THEN
  2694.         a(n)=(SHL(cdt_car,2)) OR (SHL(am_en_car,3)) OR (SHR(d1r_car,4))
  2695.       ELSE
  2696.         a(n)=(SHL(cdt_car,2)) OR (SHR(d1r_car,4)) ! d1r_car:shift right 4 x
  2697.       ENDIF
  2698.     ENDIF
  2699.   ENDIF
  2700.   cdt_car_last=cdt_car        ! Save value
  2701.   '
  2702.   end_tune_car:
  2703. RETURN
  2704. '
  2705. ' ***********************************************************************
  2706. ' FREQ-MODULATOR WILL IMPLEMENT THE FREQUENCY MODULATION MULTIPLIER
  2707. ' PARAMETER BY CALLING MULT-FREQ TO OBTAIN THE DECIMAL VALUE.  THIS IS
  2708. ' THEN STORED IN THE SYSTEM MIDI ARRAY ELEMENT.
  2709. ' ***********************************************************************
  2710. '
  2711. PROCEDURE freq_modulator
  2712.   '
  2713.   CLS
  2714.   MENU m$()                   ! show GEM menu
  2715.   n=7                         ! frequency multiplier is byte 07
  2716.   freq_mod=freq_mod_last      ! get last value for display
  2717.   mult_freq(freq_mod)         ! calculate new frequency parameter
  2718.   a(n)=freq_mod               ! store new value
  2719.   freq_mod_last=freq_mod      ! save for display
  2720.   '
  2721. RETURN
  2722. '
  2723. ' ***********************************************************************
  2724. ' FREQ-CARRIER WILL IMPLEMENT THE FREQUENCY CARRIER MULTIPLIER PARAMETER
  2725. ' BY CALLING MULT-FREQ TO OBTAIN THE DECIMAL VALUE.  THIS IS THEN STORED
  2726. ' IN THE SYSTEM MIDI ARRAY ELEMENT.
  2727. ' ***********************************************************************
  2728. '
  2729. PROCEDURE freq_carrier
  2730.   '
  2731.   CLS
  2732.   MENU m$()                        ! show GEM menu
  2733.   n=9                              ! frequency multiplier is byte 09
  2734.   freq_car=freq_car_last           ! get last value for display
  2735.   mult_freq(freq_car)              ! calculate new frequency parameter
  2736.   a(n)=freq_car                    ! store new value
  2737.   freq_car_last=freq_car           ! save for display
  2738.   '
  2739. RETURN
  2740. '
  2741. ' ***********************************************************************
  2742. ' LKS-RKS-MODULATOR WILL IMPLEMENT BOTH LKS AND RKS PARAMETER VALUES BY
  2743. ' CALLING LKS-RKS TO OBTAIN THE DECIMAL VALUES. THE LKS HI AND LKS LO
  2744. ' PARAMETERS ARE STORED IN THE SYSTEM MIDI ARRAY ELEMENTS.  THE RKS
  2745. ' VALUE IS LEFT-SHIFTED TWICE AND CHECKED AGAINST THE MSB ATTACK RATE
  2746. ' VALUE WHICH IS THEN STORED IN THE SYSTEM MIDI ARRAY ELEMENT.
  2747. ' ***********************************************************************
  2748. '
  2749. PROCEDURE lks_rks_modulator(VAR rks_mod,atk_mod)
  2750.   '
  2751.   CLS                                   ! clear screen
  2752.   MENU m$()                             ! show GEM menu
  2753.   lks_hi_mod=lks_hi_mod_last            ! get last values
  2754.   lks_lo_mod=lks_lo_mod_last
  2755.   rks_mod=rks_mod_last
  2756.   IF loaded OR received THEN            ! Exit if just updating last value
  2757.     GOTO end_lks_rks_mod
  2758.   ENDIF
  2759.   lks_rks(lks_hi_mod,lks_lo_mod,rks_mod) ! calculate new lks/rks mod values
  2760.   lks_hi_mod_last=lks_hi_mod            ! save values
  2761.   lks_lo_mod_last=lks_lo_mod
  2762.   rks_mod_last=rks_mod
  2763.   n=14                                  ! lks lo mod is byte 0E
  2764.   a(n)=lks_hi_mod                       ! store new value
  2765.   INC n                                 ! lks hi mod is byte 0F
  2766.   a(n)=lks_lo_mod                       ! store new value
  2767.   n=18                                  ! rks mod is 1st 2 bits of byte 12
  2768.   IF atk_mod=0 THEN
  2769.     a(n)=SHL(rks_mod_last,2)            ! shift left 2x
  2770.   ELSE
  2771.     a(n)=(SHL(rks_mod_last,2)) OR (SHR(atk_mod,4))
  2772.   ENDIF
  2773.   '
  2774.   end_lks_rks_mod:
  2775. RETURN
  2776. '
  2777. ' ***********************************************************************
  2778. ' LKS-RKS-CARRIER EFFECTS THE CARRIER PORTION OF THE SOUND PATCH.  SEE
  2779. ' THE ABOVE ROUTINE FOR A DETAILED DESCRIPTION.
  2780. ' ***********************************************************************
  2781. '
  2782. PROCEDURE lks_rks_carrier(VAR rks_car,atk_car)
  2783.   '
  2784.   CLS
  2785.   MENU m$()
  2786.   lks_hi_car=lks_hi_car_last
  2787.   lks_lo_car=lks_lo_car_last
  2788.   rks_car=rks_car_last
  2789.   IF loaded OR received THEN
  2790.     GOTO end_lks_rks_car
  2791.   ENDIF
  2792.   lks_rks(lks_hi_car,lks_lo_car,rks_car)
  2793.   lks_hi_car_last=lks_hi_car
  2794.   lks_lo_car_last=lks_lo_car
  2795.   rks_car_last=rks_car
  2796.   n=16                                  ! lks lo car is byte 10
  2797.   a(n)=lks_hi_car                       ! store new value
  2798.   INC n                                 ! lks hi car is byte 11
  2799.   a(n)=lks_lo_car                       ! store new value
  2800.   n=20                                  ! rks car is 1st 2 bits of byte 14
  2801.   IF a(n)=0 THEN
  2802.     a(n)=SHL(rks_car,2)                 ! shift left 2x
  2803.   ELSE
  2804.     a(n)=(SHL(rks_car,2)) OR (SHR(atk_car,4))
  2805.   ENDIF
  2806.   '
  2807.   end_lks_rks_car:
  2808. RETURN
  2809. '
  2810. ' ***********************************************************************
  2811. ' ENVELOPE-MOD WILL IMPLEMENT ALL PARAMETERS PERTAINING TO THE MODULATOR'S
  2812. ' ENVELOPING REQUIREMENTS WHICH INCLUDES THE ATTACK RATE, DECAY 1 RATE,
  2813. ' DECAY 1 LEVEL, DECAY 2 RATE, RELEASE RATE, AND SUSTAIN RELEASE RATE IF
  2814. ' SUSTAIN IS ENABLED.  AFTER CALLING THE ENVELOPE ROUTINE TO OBTAIN THE
  2815. ' DECIMAL VALUES THE MSB'S ARE CHECKED AGAINST THOSE PARAMETERS WHOSE
  2816. ' VALUES ARE INCLUDED (ATK,D1R,D2R) AND EACH VALUE, AFTER THE PROPER
  2817. ' BIT MANIPULATION, IS STORED IN THE SYSTEM MIDI ARRAY ELEMENT. THE D1L,
  2818. ' RR, AND SRR VALUES DO NOT REQUIRE ANY BIT MANIPULATION SO THEY ARE
  2819. ' JUST STORED.
  2820. ' ***********************************************************************
  2821. '
  2822. PROCEDURE envelope_mod(VAR rks_mod,atk_mod,d1r_mod,am_en_mod,cdt_mod,d2r_mod,wavform_mod)
  2823.   '
  2824.   CLS
  2825.   MENU m$()
  2826.   atk_mod=atk_mod_last
  2827.   d1r_mod=d1r_mod_last
  2828.   d1l_mod=d1l_mod_last
  2829.   d2r_mod=d2r_mod_last
  2830.   rr_mod=rr_mod_last
  2831.   srr_mod=srr_mod_last
  2832.   am_en_mod=am_en_mod_last
  2833.   IF am_en_mod=0
  2834.     am_en_mod$="OFF"
  2835.   ELSE
  2836.     am_en_mod$="ON"
  2837.   ENDIF
  2838.   IF loaded OR received THEN    ! Exit if just updating last values
  2839.     GOTO end_envelope_mod
  2840.   ENDIF
  2841.   envelope(atk_mod,d1r_mod,d1l_mod,d2r_mod,rr_mod,srr_mod,am_en_mod$)
  2842.   atk_mod_last=atk_mod
  2843.   d1r_mod_last=d1r_mod
  2844.   d1l_mod_last=d1l_mod
  2845.   d2r_mod_last=d2r_mod
  2846.   rr_mod_last=rr_mod
  2847.   srr_mod_last=srr_mod
  2848.   IF am_en_mod$="OFF"
  2849.     am_en_mod=0
  2850.   ELSE
  2851.     am_en_mod=1
  2852.   ENDIF
  2853.   am_en_mod_last=am_en_mod
  2854.   n=18                        ! atk rate MSB is last 2 bits of byte 12
  2855.   IF atk_mod>15 THEN          ! if attack rate is more than 4 bits
  2856.     a(n)=(SHR(atk_mod,4)) OR (SHL(rks_mod,2))
  2857.   ELSE
  2858.     a(n)=SHL(rks_mod,2)       !shift left 2x
  2859.   ENDIF
  2860.   INC n                       ! atk rate LSB is byte 13
  2861.   a(n)=atk_mod AND &HF        ! mask off upper bits to get LSB result
  2862.   n=22                        ! d1r rate MSB is last 2 bits of byte 16
  2863.   ' AM enable is MS bit of byte 16 also
  2864.   IF d1r_mod>15 AND am_en_mod<>0 THEN
  2865.     a(n)=(SHR(d1r_mod,4)) OR (SHL(cdt_mod,2)) OR (SHL(am_en_mod,3))
  2866.     ' d1r:shift right 4x cdt: shift left 2x am_en: shift left 3x
  2867.   ELSE
  2868.     IF d1r_mod>15 AND am_en_mod=0 THEN
  2869.       a(n)=(SHR(d1r_mod,4)) OR (SHL(cdt_mod,2))
  2870.     ELSE
  2871.       IF d1r_mod<16 AND am_en_mod<>0 THEN
  2872.         a(n)=(SHL(am_en_mod,3)) OR (SHL(cdt_mod,2))
  2873.       ELSE
  2874.         a(n)=SHL(cdt_mod,2)
  2875.       ENDIF
  2876.     ENDIF
  2877.   ENDIF
  2878.   INC n                       ! d1r rate LSB is byte 17
  2879.   a(n)=d1r_mod AND &HF        ! mask off upper bits to get LSB result
  2880.   n=26                        ! d2r rate MSB is byte 1A
  2881.   IF d2r_mod>15 THEN
  2882.     a(n)=(SHR(d2r_mod,4)) OR (SHL(wavform_mod,2))  ! same as above
  2883.   ELSE
  2884.     a(n)=SHL(wavform_mod,2)
  2885.   ENDIF
  2886.   INC n                       ! d2r rate LSB is byte 1B
  2887.   a(n)=d2r_mod AND &HF        ! mask off upper bits to get LSB result
  2888.   n=30                        ! d1l rate is byte 1E
  2889.   a(n)=d1l_mod                ! store value
  2890.   INC n                       ! release rate is byte 1F
  2891.   a(n)=rr_mod                 ! store value
  2892.   n=45                        ! sustain release rate is byte 2D
  2893.   a(n)=srr_mod                ! store value
  2894.   '
  2895.   end_envelope_mod:
  2896. RETURN
  2897. '
  2898. ' ***********************************************************************
  2899. ' ENVELOPE-CAR EFFECTS THE CARRIER PORTION OF THE SOUND PATCH.  SEE THE
  2900. ' ABOVE ROUTINE FOR A DETAILED DESCRIPTION.
  2901. ' ***********************************************************************
  2902. '
  2903. PROCEDURE envelope_car(VAR rks_car,atk_car,d1r_car,am_en_car,cdt_car,d2r_car,wavform_car)
  2904.   '
  2905.   CLS
  2906.   MENU m$()
  2907.   atk_car=atk_car_last
  2908.   d1r_car=d1r_car_last
  2909.   d1l_car=d1l_car_last
  2910.   d2r_car=d2r_car_last
  2911.   rr_car=rr_car_last
  2912.   srr_car=srr_car_last
  2913.   am_en_car=am_en_car_last
  2914.   IF am_en_car=0
  2915.     am_en_car$="OFF"
  2916.   ELSE
  2917.     am_en_car$="ON"
  2918.   ENDIF
  2919.   IF loaded OR received THEN    ! Exit if just updating last values
  2920.     GOTO end_envelope_car
  2921.   ENDIF
  2922.   envelope(atk_car,d1r_car,d1l_car,d2r_car,rr_car,srr_car,am_en_car$)
  2923.   atk_car_last=atk_car
  2924.   d1r_car_last=d1r_car
  2925.   d1l_car_last=d1l_car
  2926.   d2r_car_last=d2r_car
  2927.   rr_car_last=rr_car
  2928.   srr_car_last=srr_car
  2929.   IF am_en_car$="OFF"
  2930.     am_en_car=0
  2931.   ELSE
  2932.     am_en_car=1
  2933.   ENDIF
  2934.   am_en_car_last=am_en_car
  2935.   n=20                        ! atk rate MSB is last 2 bits of byte 14
  2936.   IF atk_car>15 THEN          ! if attack rate is more than 4 bits
  2937.     a(n)=(SHR(atk_car,4)) OR (SHL(rks_car,2))
  2938.   ELSE
  2939.     a(n)=SHL(rks_car,2)       !shift left 2x
  2940.   ENDIF
  2941.   INC n                       ! atk rate LSB is byte 15
  2942.   a(n)=atk_car AND &HF        ! mask off upper bits to get LSB result
  2943.   n=24                        ! d1r rate MSB is byte 18
  2944.   ' AM enable is MS bit of byte 18 also
  2945.   IF d1r_car>15 AND am_en_car<>0 THEN
  2946.     a(n)=(SHR(d1r_car,4)) OR (SHL(cdt_car,2)) OR (SHL(am_en_car,3))
  2947.     ' d1r:shift right 4x cdt: shift left 2x am_en: shift left 3x
  2948.   ELSE
  2949.     IF d1r_car>15 AND am_en_car=0 THEN
  2950.       a(n)=(SHR(d1r_car,4)) OR (SHL(cdt_car,2))
  2951.     ELSE
  2952.       IF d1r_car<16 AND am_en_car<>0 THEN
  2953.         a(n)=(SHL(am_en_car,3)) OR (SHL(cdt_car,2))
  2954.       ELSE
  2955.         a(n)=SHL(cdt_car,2)
  2956.       ENDIF
  2957.     ENDIF
  2958.   ENDIF
  2959.   INC n                       ! d1r rate LSB is byte 19
  2960.   a(n)=d1r_car AND &HF        ! mask off upper bits to get LSB result
  2961.   n=28                        ! d2r rate MSB is byte 1C
  2962.   IF d2r_car>15 THEN
  2963.     a(n)=(SHR(d2r_car,4)) OR (SHL(wavform_car,2))  ! same as above
  2964.   ELSE
  2965.     a(n)=SHL(wavform_car,2)
  2966.   ENDIF
  2967.   INC n                       ! d2r rate LSB is byte 1D
  2968.   a(n)=d2r_car AND &HF        ! mask off upper bits to get LSB result
  2969.   n=32                        ! d1l rate is byte 20
  2970.   a(n)=d1l_car                ! store value
  2971.   INC n                       ! release rate is byte 21
  2972.   a(n)=rr_car                 ! store value
  2973.   n=47                        ! sustain release rate is byte 2F
  2974.   a(n)=srr_car
  2975.   '
  2976.   end_envelope_car:
  2977. RETURN
  2978. '
  2979. ' ***********************************************************************
  2980. ' WAVE-MOD IMPLEMENTS THE PROPER WAVEFORM FOR THE MOULATOR PORTION OF THE
  2981. ' SOUND PATCH BY CALLING THE GENERATE-WAVE ROUTINE TO OBTAIN 4 POSSIBLE
  2982. ' WAVEFORM CHOICES.  THIS VALUE IS THEN LEFT-SHIFTED TWICE AND CHECKED
  2983. ' AGAINST THE MSB OF THE D2R VALUE AND THEN PLACED IN THE SYSTEM MIDI
  2984. ' ARRAY ELEMENT.
  2985. ' ***********************************************************************
  2986. '
  2987. PROCEDURE wave_mod(VAR wavform_mod,d2r_mod)
  2988.   '
  2989.   CLS
  2990.   MENU m$()
  2991.   wavform_mod=wavform_mod_last
  2992.   IF loaded OR received THEN    ! Exit if just updating values
  2993.     GOTO end_wave_mod
  2994.   ENDIF
  2995.   generate_wave(wavform_mod)
  2996.   wavform_mod_last=wavform_mod
  2997.   n=26
  2998.   IF d2r_mod=0 THEN
  2999.     a(n)=SHL(wavform_mod,2)
  3000.   ELSE
  3001.     a(n)=(SHL(wavform_mod,2)) OR (SHR(d2r_mod,4))
  3002.   ENDIF
  3003.   '
  3004.   end_wave_mod:
  3005. RETURN
  3006. '
  3007. ' ***********************************************************************
  3008. ' WAVE-CAR EFFECTS THE CARRIER PORTION OF THE SOUND PATCH.  SEE THE
  3009. ' ABOVE ROUTINE FOR A DETAILED DESCRIPTION.
  3010. ' ***********************************************************************
  3011. '
  3012. PROCEDURE wave_car(VAR wavform_car,d2r_car)
  3013.   '
  3014.   CLS
  3015.   MENU m$()
  3016.   wavform_car=wavform_car_last
  3017.   IF loaded OR received THEN
  3018.     GOTO end_wave_car
  3019.   ENDIF
  3020.   generate_wave(wavform_car)
  3021.   wavform_car_last=wavform_car
  3022.   n=28
  3023.   IF d2r_car=0 THEN
  3024.     a(n)=SHL(wavform_car,2)
  3025.   ELSE
  3026.     a(n)=(SHL(wavform_car,2)) OR (SHR(d2r_car,4))
  3027.   ENDIF
  3028.   '
  3029.   end_wave_car:
  3030. RETURN
  3031. '
  3032. ' ***********************************************************************
  3033. ' THE NEXT SET OF ROUTINES OBTAIN A PARAMETER IN DECIMAL FORM BASED ON
  3034. ' MOUSE ENTRIES.  FIRST, A VALUE IS INITIALIZED TO 0 IF IT WAS NEVER
  3035. ' UPDATED.  A DISPLAY PROMPT IS SHOWN WITH A GRAPHICAL BOX IN WHICH CASE
  3036. ' THE USER WILL USE THE LEFT MOUSE BUTTON TO INCREMENT OR RIGHT MOUSE
  3037. ' BUTTON TO DECREMENT A DECIMAL VALUE BASED ON A GIVEN MINIMUM AND
  3038. ' MAXIMUM RANGE. EACH ROUTINE IS EXITED WHEN BOTH MOUSE BUTTONS ARE
  3039. ' DEPRESSED. THE FOLLOWING PROVIDES INFORMATION ON THE MINIMUM AND
  3040. ' MAXIMUM RANGE VALUES FOR EACH PARAMETER:
  3041. '
  3042. '         FINE DE-TUNE -  -7 TO 7
  3043. '         COURSE DE-TUNE - 0 OR 1
  3044. '         FREQUENCY MULTIPLIER - 0 TO 15
  3045. '         MODULATION LEVEL - 0 TO 99
  3046. '         TOTAL LEVEL - 0 TO 99
  3047. '         FEEDBACK LEVEL - 0 TO 7
  3048. '         AMPLITUDE MOULATION SENSITIVITY - 0 TO 3
  3049. '         FM(VIBRATO) ENABLE - 0 OR 1
  3050. '         FREQUENCY MODULATION SENSITIVITY - 0 TO 7
  3051. '         FM DELAY TIME- 0 TO 127
  3052. '         SUSTAIN ENABLE - 0 OR 1
  3053. '         LEVEL KEY SCALE HI - 0 TO 15
  3054. '         LEVEL KEY SCALE LO - 0 TO 15
  3055. '         RATE KEY SCALE - 0 TO 3
  3056. '         ATTACK RATE - 0 TO 63
  3057. '         DECAY 1 RATE - 0 TO 63
  3058. '         DECAY 1 LEVEL - 0 TO 15
  3059. '         DECAY 2 RATE - 0 TO 63
  3060. '         RELEASE RATE - 0 TO 15
  3061. '         SUSTAIN RELEASE RATE - 0 TO 15
  3062. '
  3063. ' THE CREATE-BOX/REDRAW-BOX ROUTINES ARE CALLED EACH TIME THE VALUE
  3064. ' CHANGES WITH THE 4 X,Y COORDINATES OF EACH BOX BEING PASSED TO
  3065. ' EACH ROUTINE.  BOTH THE LEVELING, AM/FM ROUTINES CALCULATE THE
  3066. ' SYSTEM MIDI ARRAY ELEMENTS.
  3067. ' ***********************************************************************
  3068. '
  3069. PROCEDURE fine_detune(VAR dt,cdt$)
  3070.   '
  3071.   IF dt=0 THEN
  3072.     dt$="0"                   !reinitialize fine detune if not used
  3073.   ENDIF
  3074.   fdt$="Fine Detune:"
  3075.   x0=350
  3076.   y0=36
  3077.   x1=400
  3078.   y1=60                       !dt box coordinates
  3079.   dt$=STR$(dt)
  3080.   create_box(fdt$,dt$,x0,y0,x1,y1)
  3081.   cdt_prompt$="Course Detune:"
  3082.   v0=350
  3083.   w0=76
  3084.   v1=410
  3085.   w1=100                      ! cdt box coordinates
  3086.   create_box(cdt_prompt$,cdt$,v0,w0,v1,w1)
  3087.   DO
  3088.     a=MOUSEX                  !get mouse coordinates
  3089.     b=MOUSEY
  3090.     IF MOUSEK=1               !left mouse button
  3091.       IF a>x0 AND b>y0 AND a<x1 AND b<y1
  3092.         IF dt<7 THEN
  3093.           INC dt              !increment fine detune
  3094.           dt$=STR$(dt)
  3095.           redraw_box(dt$,x0,y0,x1,y1)
  3096.           PAUSE 10            !delay for mouse button
  3097.         ENDIF
  3098.       ELSE
  3099.         IF a>v0 AND b>w0 AND a<v1 AND b<w1
  3100.           cdt$="ON"
  3101.           redraw_box(cdt$,v0,w0,v1,w1)
  3102.           PAUSE 10          !delay for mouse button
  3103.         ENDIF
  3104.       ENDIF
  3105.     ELSE
  3106.       IF MOUSEK=2 THEN        !right mouse button
  3107.         IF a>x0 AND b>y0 AND a<x1 AND b<y1
  3108.           IF dt>-7 THEN
  3109.             DEC dt            !decrement detune
  3110.             dt$=STR$(dt)
  3111.             redraw_box(dt$,x0,y0,x1,y1)
  3112.             PAUSE 10          !delay for mouse button
  3113.           ENDIF
  3114.         ELSE
  3115.           IF a>v0 AND b>w0 AND a<v1 AND b<w1
  3116.             cdt$="OFF"
  3117.             redraw_box(cdt$,v0,w0,v1,w1)
  3118.             PAUSE 10        !delay for mouse button
  3119.           ENDIF
  3120.         ENDIF
  3121.       ENDIF
  3122.     ENDIF
  3123.     EXIT IF MOUSEK=3          !exit loop for both buttons
  3124.   LOOP
  3125. RETURN
  3126. '
  3127. PROCEDURE mult_freq(VAR freq)
  3128.   '
  3129.   IF freq=0 THEN
  3130.     freq$="0"                 !reinitialize frequency multiplier
  3131.   ENDIF
  3132.   freqprompt$="Frequency Mulitplier:"
  3133.   x0=350
  3134.   y0=36
  3135.   x1=400
  3136.   y1=60                       !freq box coordinates
  3137.   freq$=STR$(freq)
  3138.   create_box(freqprompt$,freq$,x0,y0,x1,y1)
  3139.   DO
  3140.     a=MOUSEX                  !get mouse coordinates
  3141.     b=MOUSEY
  3142.     IF MOUSEK=1               !left mouse button
  3143.       IF a>x0 AND b>y0 AND a<x1 AND b<y1
  3144.         IF freq<15 THEN
  3145.           INC freq            !increment multiplier
  3146.           freq$=STR$(freq)
  3147.           redraw_box(freq$,x0,y0,x1,y1)
  3148.           PAUSE 10            !delay for mouse button
  3149.         ENDIF
  3150.       ENDIF
  3151.     ELSE
  3152.       IF MOUSEK=2 THEN        !right mouse button
  3153.         IF a>x0 AND b>y0 AND a<x1 AND b<y1
  3154.           IF freq>0 THEN
  3155.             DEC freq          !decrement multiplier
  3156.             freq$=STR$(freq)
  3157.             redraw_box(freq$,x0,y0,x1,y1)
  3158.             PAUSE 10          !delay for mouse button
  3159.           ENDIF
  3160.         ENDIF
  3161.       ENDIF
  3162.     ENDIF
  3163.     EXIT IF MOUSEK=3          !exit loop for both buttons
  3164.   LOOP
  3165. RETURN
  3166. '
  3167. PROCEDURE leveling
  3168.   '
  3169.   CLS
  3170.   MENU m$()
  3171.   IF mod_level=0 THEN
  3172.     mod_level$="0"            !reinitialize modulation leveling
  3173.   ENDIF
  3174.   IF total_level=0 THEN
  3175.     total_level$="0"          !reinitialize total leveling
  3176.   ENDIF
  3177.   IF fb_level=0 THEN
  3178.     fb_level$="0"             !reinitialize feedback leveling
  3179.   ENDIF
  3180.   mod_level_prompt$="Modulation level:"
  3181.   x0=350
  3182.   y0=36
  3183.   x1=400
  3184.   y1=60                       !mod level box coordinates
  3185.   mod_level$=STR$(mod_level)
  3186.   create_box(mod_level_prompt$,mod_level$,x0,y0,x1,y1)
  3187.   total_level_prompt$="Total level:"
  3188.   v0=350
  3189.   w0=76
  3190.   v1=400
  3191.   w1=100                      !total level box coordinates
  3192.   total_level$=STR$(total_level)
  3193.   create_box(total_level_prompt$,total_level$,v0,w0,v1,w1)
  3194.   fb_level_prompt$="Feedback level:"
  3195.   t0=350
  3196.   u0=116
  3197.   t1=400
  3198.   u1=140                      !total level box coordinates
  3199.   fb_level$=STR$(fb_level)
  3200.   create_box(fb_level_prompt$,fb_level$,t0,u0,t1,u1)
  3201.   DO
  3202.     a=MOUSEX                  !get mouse coordinates
  3203.     b=MOUSEY
  3204.     IF MOUSEK=1               !left mouse button
  3205.       IF a>x0 AND b>y0 AND a<x1 AND b<y1
  3206.         IF mod_level<99 THEN
  3207.           INC mod_level       !increment mod level
  3208.           mod_level$=STR$(mod_level)
  3209.           redraw_box(mod_level$,x0,y0,x1,y1)
  3210.           PAUSE 3             !delay for mouse button
  3211.         ENDIF
  3212.       ELSE
  3213.         IF a>v0 AND b>w0 AND a<v1 AND b<w1
  3214.           IF total_level<99 THEN
  3215.             INC total_level   !increment total level
  3216.             total_level$=STR$(total_level)
  3217.             redraw_box(total_level$,v0,w0,v1,w1)
  3218.             PAUSE 3           !delay for mouse button
  3219.           ENDIF
  3220.         ELSE
  3221.           IF a>t0 AND b>u0 AND a<t1 AND b<u1
  3222.             IF fb_level<7 THEN
  3223.               INC fb_level    !increment feedback level
  3224.               fb_level$=STR$(fb_level)
  3225.               redraw_box(fb_level$,t0,u0,t1,u1)
  3226.               PAUSE 10        !delay for mouse button
  3227.             ENDIF
  3228.           ENDIF
  3229.         ENDIF
  3230.       ENDIF
  3231.     ELSE
  3232.       IF MOUSEK=2 THEN        !right mouse button
  3233.         IF a>x0 AND b>y0 AND a<x1 AND b<y1
  3234.           IF mod_level>0 THEN
  3235.             DEC mod_level     !decrement mod level
  3236.             mod_level$=STR$(mod_level)
  3237.             redraw_box(mod_level$,x0,y0,x1,y1)
  3238.             PAUSE 3           !delay for mouse button
  3239.           ENDIF
  3240.         ELSE
  3241.           IF a>v0 AND b>w0 AND a<v1 AND b<w1
  3242.             IF total_level>0 THEN
  3243.               DEC total_level !decrement total level
  3244.               total_level$=STR$(total_level)
  3245.               redraw_box(total_level$,v0,w0,v1,w1)
  3246.               PAUSE 3         !delay for mouse button
  3247.             ENDIF
  3248.           ELSE
  3249.             IF a>t0 AND b>u0 AND a<t1 AND b<u1
  3250.               IF fb_level>0 THEN
  3251.                 DEC fb_level       !decrement feedback level
  3252.                 fb_level$=STR$(fb_level)
  3253.                 redraw_box(fb_level$,t0,u0,t1,u1)
  3254.                 PAUSE 10           !delay for mouse button
  3255.               ENDIF
  3256.             ENDIF
  3257.           ENDIF
  3258.         ENDIF
  3259.       ENDIF
  3260.     ENDIF
  3261.     EXIT IF MOUSEK=3               !exit loop for both buttons
  3262.   LOOP
  3263.   n=10                             !modulation leveling (MSB) is byte 0A
  3264.   new_mod_level=99-mod_level       !calculate values
  3265.   new_total_level=99-total_level
  3266.   IF new_mod_level=99 THEN         !for null value byte 0A--> 07
  3267.     temp=7
  3268.   ELSE
  3269.     temp=(new_mod_level AND &HF0)/16    !temp:shift right 4x/mask 4 lower bits
  3270.   ENDIF
  3271.   a(n)=temp                   !store split value
  3272.   INC n                       !modulation leveling (LSB) is byte 0B
  3273.   IF new_mod_level=99 THEN    !for null value byte 0B --> 0F
  3274.     temp=15
  3275.   ELSE
  3276.     temp=new_mod_level AND &HF   !temp:mask upper 4 bits
  3277.   ENDIF
  3278.   a(n)=temp                   !store split value
  3279.   INC n                       !total leveling (MSB) is byte 0C
  3280.   IF new_total_level=99 THEN
  3281.     temp=7
  3282.   ELSE
  3283.     temp=(new_total_level AND &HF0)/16
  3284.   ENDIF
  3285.   a(n)=temp
  3286.   INC n                       !modulation leveling (LSB) is byte 0D
  3287.   IF new_total_level=99 THEN
  3288.     temp=15
  3289.   ELSE
  3290.     temp=new_total_level AND &HF
  3291.   ENDIF
  3292.   a(n)=temp
  3293.   n=34                             !feedback leveling (MSB) is byte 22
  3294.   a(n)=(fb_level AND &H6)/2        !MSB:mask 1st 2 bits shift right 1x
  3295.   INC n                            !feedback leveling (LSB) is byte 23
  3296.   a(n)=(fb_level AND &H1)*8        !LSB:mask last bit shift left 3x
  3297.   '
  3298. RETURN
  3299. '
  3300. PROCEDURE am_fm
  3301.   '
  3302.   CLS
  3303.   MENU m$()
  3304.   IF ams=0 THEN
  3305.     ams$="0"                        !reinitialize AM sensitivity
  3306.   ENDIF
  3307.   IF fm_en=0 THEN
  3308.     fm_en$="OFF"                    !reinitialize FM enable
  3309.   ELSE
  3310.     fm_en$="ON"
  3311.   ENDIF
  3312.   IF pms=0 THEN
  3313.     pms$="0"                        !reinitialize FM sensitivity
  3314.   ENDIF
  3315.   IF fm_delay=0 THEN
  3316.     fm_delay$="0"                   !reinitialize FM delay time
  3317.   ENDIF
  3318.   IF sus_en=0 THEN
  3319.     sus_en$="OFF"                   !reinitialize sustain enable
  3320.   ELSE
  3321.     sus_en$="ON"
  3322.   ENDIF
  3323.   ams_prompt$="AM Sensitivity:"
  3324.   x0=350
  3325.   y0=20
  3326.   x1=400
  3327.   y1=44                                 !ams box coordinates
  3328.   ams$=STR$(ams)
  3329.   create_box(ams_prompt$,ams$,x0,y0,x1,y1)
  3330.   fm_en_prompt$="FM enable:"
  3331.   v0=350
  3332.   w0=50
  3333.   v1=410
  3334.   w1=74                                !fm en box coordinates
  3335.   create_box(fm_en_prompt$,fm_en$,v0,w0,v1,w1)
  3336.   pms_prompt$="FM Sensitivity:"
  3337.   t0=350
  3338.   u0=80
  3339.   t1=400
  3340.   u1=104                                !pms box coordinates
  3341.   pms$=STR$(pms)
  3342.   create_box(pms_prompt$,pms$,t0,u0,t1,u1)
  3343.   fm_delay_prompt$="FM delay:"
  3344.   r0=350
  3345.   s0=110
  3346.   r1=420
  3347.   s1=134                                !fm delay box coordinates
  3348.   fm_delay$=STR$(fm_delay)
  3349.   create_box(fm_delay_prompt$,fm_delay$,r0,s0,r1,s1)
  3350.   sus_en_prompt$="Sustain Enable:"
  3351.   p0=350
  3352.   q0=140
  3353.   p1=410
  3354.   q1=164                                !sustain en box coordinates
  3355.   create_box(sus_en_prompt$,sus_en$,p0,q0,p1,q1)
  3356.   DO
  3357.     a=MOUSEX                            !get mouse coordinates
  3358.     b=MOUSEY
  3359.     IF MOUSEK=1                         !left mouse button
  3360.       IF a>x0 AND b>y0 AND a<x1 AND b<y1
  3361.         IF ams<3 THEN
  3362.           INC ams                     !increment ams
  3363.           ams$=STR$(ams)
  3364.           redraw_box(ams$,x0,y0,x1,y1)
  3365.           PAUSE 10                    !delay for mouse button
  3366.         ENDIF
  3367.       ELSE
  3368.         IF a>v0 AND b>w0 AND a<v1 AND b<w1
  3369.           fm_en$="ON"
  3370.           redraw_box(fm_en$,v0,w0,v1,w1)
  3371.           PAUSE 10                  !delay for mouse button
  3372.         ELSE
  3373.           IF a>t0 AND b>u0 AND a<t1 AND b<u1
  3374.             IF pms<7 THEN
  3375.               INC pms                 !increment pms
  3376.               pms$=STR$(pms)
  3377.               redraw_box(pms$,t0,u0,t1,u1)
  3378.               PAUSE 10                !delay for mouse button
  3379.             ENDIF
  3380.           ELSE
  3381.             IF a>r0 AND b>s0 AND a<r1 AND b<s1
  3382.               IF fm_delay<127 THEN
  3383.                 INC fm_delay          !increment fm delay
  3384.                 fm_delay$=STR$(fm_delay)
  3385.                 redraw_box(fm_delay$,r0,s0,r1,s1)
  3386.                 PAUSE 3               !delay for mouse button
  3387.               ENDIF
  3388.             ELSE
  3389.               IF a>p0 AND b>q0 AND a<p1 AND b<q1
  3390.                 sus_en$="ON"
  3391.                 redraw_box(sus_en$,p0,q0,p1,q1)
  3392.                 PAUSE 10            !delay for mouse button
  3393.               ENDIF
  3394.             ENDIF
  3395.           ENDIF
  3396.         ENDIF
  3397.       ENDIF
  3398.     ELSE
  3399.       IF MOUSEK=2                         !right mouse button
  3400.         IF a>x0 AND b>y0 AND a<x1 AND b<y1
  3401.           IF ams>0 THEN
  3402.             DEC ams                     !decrement ams
  3403.             ams$=STR$(ams)
  3404.             redraw_box(ams$,x0,y0,x1,y1)
  3405.             PAUSE 10                    !delay for mouse button
  3406.           ENDIF
  3407.         ELSE
  3408.           IF a>v0 AND b>w0 AND a<v1 AND b<w1
  3409.             fm_en$="OFF"
  3410.             redraw_box(fm_en$,v0,w0,v1,w1)
  3411.             PAUSE 10                  !delay for mouse button
  3412.           ELSE
  3413.             IF a>t0 AND b>u0 AND a<t1 AND b<u1
  3414.               IF pms>0 THEN
  3415.                 DEC pms                 !decrement pms
  3416.                 pms$=STR$(pms)
  3417.                 redraw_box(pms$,t0,u0,t1,u1)
  3418.                 PAUSE 10                !delay for mouse button
  3419.               ENDIF
  3420.             ELSE
  3421.               IF a>r0 AND b>s0 AND a<r1 AND b<s1
  3422.                 IF fm_delay>0 THEN
  3423.                   DEC fm_delay          !decrement fm delay
  3424.                   fm_delay$=STR$(fm_delay)
  3425.                   redraw_box(fm_delay$,r0,s0,r1,s1)
  3426.                   PAUSE 3               !delay for mouse button
  3427.                 ENDIF
  3428.               ELSE
  3429.                 IF a>p0 AND b>q0 AND a<p1 AND b<q1
  3430.                   sus_en$="OFF"
  3431.                   redraw_box(sus_en$,p0,q0,p1,q1)
  3432.                   PAUSE 10                  !delay for mouse button
  3433.                 ENDIF
  3434.               ENDIF
  3435.             ENDIF
  3436.           ENDIF
  3437.         ENDIF
  3438.       ENDIF
  3439.     ENDIF
  3440.     EXIT IF MOUSEK=3
  3441.   LOOP
  3442.   n=37
  3443.   ' Amplitude Modulation Sensitivity is byte 25
  3444.   a(n)=ams
  3445.   ' Pitch Modulation Sensitivity is byte 24
  3446.   DEC n
  3447.   a(n)=pms
  3448.   n=48
  3449.   ' FM delay time are bytes 30 & 31
  3450.   a(n)=SHR((fm_delay AND &HF0),4)
  3451.   INC n
  3452.   a(n)=fm_delay AND &HF
  3453.   n=52
  3454.   ' FM Enable/Sustain Enable is first 2 bits of byte 34
  3455.   IF fm_en$="OFF" THEN
  3456.     fm_en=0
  3457.   ELSE
  3458.     fm_en=1
  3459.   ENDIF
  3460.   IF sus_en$="OFF" THEN
  3461.     sus_en=0
  3462.   ELSE
  3463.     sus_en=1
  3464.   ENDIF
  3465.   a(n)=SHL(fm_en,3) OR SHL(sus_en,2)
  3466.   '
  3467. RETURN
  3468. '
  3469. PROCEDURE lks_rks(VAR lks_hi,lks_lo,rks)
  3470.   '
  3471.   IF lks_hi=0 THEN
  3472.     lks_hi$="0"                     !reinitialize level key scaling hi
  3473.   ENDIF
  3474.   IF lks_lo=0 THEN
  3475.     lks_lo$="0"                     !reinitialize level key scaling lo
  3476.   ENDIF
  3477.   IF rks=0 THEN
  3478.     rks$="0"                        !reinitialize rate key scaling
  3479.   ENDIF
  3480.   lks_hi_prompt$="Level Key Scale hi:"
  3481.   x0=350
  3482.   y0=36
  3483.   x1=400
  3484.   y1=60                                 !lks hi box coordinates
  3485.   lks_hi$=STR$(lks_hi)
  3486.   create_box(lks_hi_prompt$,lks_hi$,x0,y0,x1,y1)
  3487.   lks_lo_prompt$="Level Key Scale lo:"
  3488.   v0=350
  3489.   w0=76
  3490.   v1=400
  3491.   w1=100                                 !lks lo box coordinates
  3492.   lks_lo$=STR$(lks_lo)
  3493.   create_box(lks_lo_prompt$,lks_lo$,v0,w0,v1,w1)
  3494.   rks_prompt$="Rate Key Scale:"
  3495.   t0=350
  3496.   u0=116
  3497.   t1=400
  3498.   u1=140                                !rks box coordinates
  3499.   rks$=STR$(rks)
  3500.   create_box(rks_prompt$,rks$,t0,u0,t1,u1)
  3501.   DO
  3502.     a=MOUSEX                            !get mouse coordinates
  3503.     b=MOUSEY
  3504.     IF MOUSEK=1                         !left mouse button
  3505.       IF a>x0 AND b>y0 AND a<x1 AND b<y1
  3506.         IF lks_hi<15 THEN
  3507.           INC lks_hi                !increment lks hi
  3508.           lks_hi$=STR$(lks_hi)
  3509.           redraw_box(lks_hi$,x0,y0,x1,y1)
  3510.           PAUSE 10                      !delay for mouse button
  3511.         ENDIF
  3512.       ELSE
  3513.         IF a>v0 AND b>w0 AND a<v1 AND b<w1
  3514.           IF lks_lo<15 THEN
  3515.             INC lks_lo              !increment lks lo
  3516.             lks_lo$=STR$(lks_lo)
  3517.             redraw_box(lks_lo$,v0,w0,v1,w1)
  3518.             PAUSE 10                    !delay for mouse button
  3519.           ENDIF
  3520.         ELSE
  3521.           IF a>t0 AND b>u0 AND a<t1 AND b<u1
  3522.             IF rks<3 THEN
  3523.               INC rks                   !increment rks
  3524.               rks$=STR$(rks)
  3525.               redraw_box(rks$,t0,u0,t1,u1)
  3526.               PAUSE 10                  !delay for mouse button
  3527.             ENDIF
  3528.           ENDIF
  3529.         ENDIF
  3530.       ENDIF
  3531.     ELSE
  3532.       IF MOUSEK=2                       !right mouse button
  3533.         IF a>x0 AND b>y0 AND a<x1 AND b<y1
  3534.           IF lks_hi>0 THEN
  3535.             DEC lks_hi                  !decrement lks hi
  3536.             lks_hi$=STR$(lks_hi)
  3537.             redraw_box(lks_hi$,x0,y0,x1,y1)
  3538.             PAUSE 10                    !delay for mouse button
  3539.           ENDIF
  3540.         ELSE
  3541.           IF a>v0 AND b>w0 AND a<v1 AND b<w1
  3542.             IF lks_lo>0 THEN
  3543.               DEC lks_lo              !decrement lks lo
  3544.               lks_lo$=STR$(lks_lo)
  3545.               redraw_box(lks_lo$,v0,w0,v1,w1)
  3546.               PAUSE 10                !delay for mouse button
  3547.             ENDIF
  3548.           ELSE
  3549.             IF a>t0 AND b>u0 AND a<t1 AND b<u1
  3550.               IF rks>0 THEN
  3551.                 DEC rks              !decrement rks
  3552.                 rks$=STR$(rks)
  3553.                 redraw_box(rks$,t0,u0,t1,u1)
  3554.                 PAUSE 10             !delay for mouse button
  3555.               ENDIF
  3556.             ENDIF
  3557.           ENDIF
  3558.         ENDIF
  3559.       ENDIF
  3560.     ENDIF
  3561.     EXIT IF MOUSEK=3                 !exit loop for both buttons
  3562.   LOOP
  3563. RETURN
  3564. '
  3565. PROCEDURE envelope(VAR atk,d1r,d1l,d2r,rr,srr,am_en$)
  3566.   '
  3567.   IF rez=2 THEN
  3568.     CLS
  3569.   ENDIF
  3570.   BOX 0,10,410,185
  3571.   IF atk=0 THEN
  3572.     atk$="0"                  !reinitialize attack rate
  3573.   ENDIF
  3574.   IF d1r=0 THEN
  3575.     d1r$="0"                  !reinitialize decay 1 rate
  3576.   ENDIF
  3577.   IF d1l=0 THEN
  3578.     d1l$="0"                  !reinitialize decay 1 level
  3579.   ENDIF
  3580.   IF d2r=0 THEN
  3581.     d2r$="0"                  !reinitialize decay 2 rate
  3582.   ENDIF
  3583.   IF rr=0 THEN
  3584.     rr$="0"                   !reinitialize release rate
  3585.   ENDIF
  3586.   IF srr=0 THEN
  3587.     srr$="0"                  !reinitialize sustain release rate
  3588.   ENDIF
  3589.   atk_prompt$="Attack Rate:"
  3590.   x0=350
  3591.   y0=10
  3592.   x1=410
  3593.   y1=35                       !atk box coordinates
  3594.   atk$=STR$(atk)
  3595.   create_box(atk_prompt$,atk$,x0,y0,x1,y1)
  3596.   d1r_prompt$="Decay 1 Rate:"
  3597.   v0=350
  3598.   w0=35
  3599.   v1=410
  3600.   w1=60                       !d1r box coordinates
  3601.   d1r$=STR$(d1r)
  3602.   create_box(d1r_prompt$,d1r$,v0,w0,v1,w1)
  3603.   d1l_prompt$="Decay 1 Level:"
  3604.   t0=350
  3605.   u0=60
  3606.   t1=410
  3607.   u1=85                       !d1l box coordinates
  3608.   d1l$=STR$(d1l)
  3609.   create_box(d1l_prompt$,d1l$,t0,u0,t1,u1)
  3610.   d2r_prompt$="Decay 2 Rate:"
  3611.   r0=350
  3612.   s0=85
  3613.   r1=410
  3614.   s1=110                      !d2r box coordinates
  3615.   d2r$=STR$(d2r)
  3616.   create_box(d2r_prompt$,d2r$,r0,s0,r1,s1)
  3617.   rr_prompt$="Release Rate:"
  3618.   p0=350
  3619.   q0=110
  3620.   p1=410
  3621.   q1=135                      !rr box coordinates
  3622.   rr$=STR$(rr)
  3623.   create_box(rr_prompt$,rr$,p0,q0,p1,q1)
  3624.   srr_prompt$="Sustain Release Rate:"
  3625.   n0=350
  3626.   o0=135
  3627.   n1=410
  3628.   o1=160                      !srr box coordinates
  3629.   srr$=STR$(srr)
  3630.   create_box(srr_prompt$,srr$,n0,o0,n1,o1)
  3631.   am_en_prompt$="AM Enable:"
  3632.   l0=350
  3633.   m0=160
  3634.   l1=410
  3635.   m1=185                      !am en box coordinates
  3636.   create_box(am_en_prompt$,am_en$,l0,m0,l1,m1)
  3637.   DO
  3638.     a=MOUSEX                            !get mouse coordinates
  3639.     b=MOUSEY
  3640.     IF MOUSEK=1                         !left mouse button
  3641.       IF a>x0 AND b>y0 AND a<x1 AND b<y1
  3642.         IF atk<63 THEN
  3643.           INC atk                       !increment atk
  3644.           atk$=STR$(atk)
  3645.           redraw_box(atk$,x0,y0,x1,y1)
  3646.           PAUSE 3                       !delay for mouse button
  3647.         ENDIF
  3648.       ELSE
  3649.         IF a>v0 AND b>w0 AND a<v1 AND b<w1
  3650.           IF d1r<63 THEN
  3651.             INC d1r                       !increment d1r
  3652.             d1r$=STR$(d1r)
  3653.             redraw_box(d1r$,v0,w0,v1,w1)
  3654.             PAUSE 3                       !delay for mouse button
  3655.           ENDIF
  3656.         ELSE
  3657.           IF a>t0 AND b>u0 AND a<t1 AND b<u1
  3658.             IF d1l<15 THEN
  3659.               INC d1l                       !increment d1l
  3660.               d1l$=STR$(d1l)
  3661.               redraw_box(d1l$,t0,u0,t1,u1)
  3662.               PAUSE 10                       !delay for mouse button
  3663.             ENDIF
  3664.           ELSE
  3665.             IF a>r0 AND b>s0 AND a<r1 AND b<s1
  3666.               IF d2r<63 THEN
  3667.                 INC d2r                       !increment d2r
  3668.                 d2r$=STR$(d2r)
  3669.                 redraw_box(d2r$,r0,s0,r1,s1)
  3670.                 PAUSE 3                       !delay for mouse button
  3671.               ENDIF
  3672.             ELSE
  3673.               IF a>p0 AND b>q0 AND a<p1 AND b<q1
  3674.                 IF rr<15 THEN
  3675.                   INC rr                        !increment rr
  3676.                   rr$=STR$(rr)
  3677.                   redraw_box(rr$,p0,q0,p1,q1)
  3678.                   PAUSE 10                      !delay for mouse button
  3679.                 ENDIF
  3680.               ELSE
  3681.                 IF a>n0 AND b>o0 AND a<n1 AND b<o1
  3682.                   IF srr<15 THEN
  3683.                     INC srr                       !increment srr
  3684.                     srr$=STR$(srr)
  3685.                     redraw_box(srr$,n0,o0,n1,o1)
  3686.                     PAUSE 10                      !delay for mouse button
  3687.                   ENDIF
  3688.                 ELSE
  3689.                   IF a>l0 AND b>m0 AND a<l1 AND b<m1
  3690.                     am_en$="ON"
  3691.                     redraw_box(am_en$,l0,m0,l1,m1)
  3692.                     PAUSE 10                      !delay for mouse button
  3693.                   ENDIF
  3694.                 ENDIF
  3695.               ENDIF
  3696.             ENDIF
  3697.           ENDIF
  3698.         ENDIF
  3699.       ENDIF
  3700.     ELSE
  3701.       IF MOUSEK=2                         !right mouse button
  3702.         IF a>x0 AND b>y0 AND a<x1 AND b<y1
  3703.           IF atk>0 THEN
  3704.             DEC atk                       !decrement atk
  3705.             atk$=STR$(atk)
  3706.             redraw_box(atk$,x0,y0,x1,y1)
  3707.             PAUSE 3                       !delay for mouse button
  3708.           ENDIF
  3709.         ELSE
  3710.           IF a>v0 AND b>w0 AND a<v1 AND b<w1
  3711.             IF d1r>0 THEN
  3712.               DEC d1r                       !decrement d1r
  3713.               d1r$=STR$(d1r)
  3714.               redraw_box(d1r$,v0,w0,v1,w1)
  3715.               PAUSE 3                       !delay for mouse button
  3716.             ENDIF
  3717.           ELSE
  3718.             IF a>t0 AND b>u0 AND a<t1 AND b<u1
  3719.               IF d1l>0 THEN
  3720.                 DEC d1l                     !decrement d1l
  3721.                 d1l$=STR$(d1l)
  3722.                 redraw_box(d1l$,t0,u0,t1,u1)
  3723.                 PAUSE 10                    !delay for mouse button
  3724.               ENDIF
  3725.             ELSE
  3726.               IF a>r0 AND b>s0 AND a<r1 AND b<s1
  3727.                 IF d2r>0 THEN
  3728.                   DEC d2r                   !decrement d2r
  3729.                   d2r$=STR$(d2r)
  3730.                   redraw_box(d2r$,r0,s0,r1,s1)
  3731.                   PAUSE 3                   !delay for mouse button
  3732.                 ENDIF
  3733.               ELSE
  3734.                 IF a>p0 AND b>q0 AND a<p1 AND b<q1
  3735.                   IF rr>0 THEN
  3736.                     DEC rr                  !decrement rr
  3737.                     rr$=STR$(rr)
  3738.                     redraw_box(rr$,p0,q0,p1,q1)
  3739.                     PAUSE 10                !delay for mouse button
  3740.                   ENDIF
  3741.                 ELSE
  3742.                   IF a>n0 AND b>o0 AND a<n1 AND b<o1
  3743.                     IF srr>0 THEN
  3744.                       DEC srr               !decrement srr
  3745.                       srr$=STR$(srr)
  3746.                       redraw_box(srr$,n0,o0,n1,o1)
  3747.                       PAUSE 10              !delay for mouse button
  3748.                     ENDIF
  3749.                   ELSE
  3750.                     IF a>l0 AND b>m0 AND a<l1 AND b<m1
  3751.                       am_en$="OFF"
  3752.                       redraw_box(am_en$,l0,m0,l1,m1)
  3753.                       PAUSE 10            !delay for mouse button
  3754.                     ENDIF
  3755.                   ENDIF
  3756.                 ENDIF
  3757.               ENDIF
  3758.             ENDIF
  3759.           ENDIF
  3760.         ENDIF
  3761.       ENDIF
  3762.     ENDIF
  3763.     EXIT IF MOUSEK=3                          !exit for both buttons
  3764.   LOOP
  3765. RETURN
  3766. '
  3767. PROCEDURE generate_wave(VAR wavform)
  3768.   '
  3769.   lx=190
  3770.   rx=450
  3771.   ty=45
  3772.   by=180
  3773.   '
  3774.   SGET tempuse$
  3775.   GRAPHMODE 1
  3776.   DEFFILL 1,2,2
  3777.   DEFTEXT 1,0,0,6
  3778.   DEFLINE 1,3
  3779.   growbox(lx,ty,10,10,lx,ty,rx-lx,by-ty)
  3780.   PBOX lx,ty,rx,by
  3781.   BOX lx,ty,rx,by
  3782.   DEFLINE 1,1
  3783.   TEXT lx+30,ty+10,"     Waveform Shape     "
  3784.   DEFFILL 1,2,8
  3785.   PBOX lx+25,ty+25,rx-200,ty+40
  3786.   PBOX lx+25,ty+45,rx-200,ty+60
  3787.   PBOX lx+25,ty+65,rx-200,by-55
  3788.   PBOX lx+25,by-50,rx-200,by-35
  3789.   PBOX lx+115,by-20,rx-110,by-5
  3790.   DEFFILL 0,2,8
  3791.   PBOX lx+25,ty+25,rx-203,ty+39
  3792.   PBOX lx+25,ty+45,rx-203,ty+59
  3793.   PBOX lx+25,ty+65,rx-203,by-56
  3794.   PBOX lx+25,by-50,rx-203,by-36
  3795.   PBOX lx+115,by-20,rx-113,by-6
  3796.   BOX lx+25,ty+25,rx-203,ty+39
  3797.   BOX lx+27,ty+27,rx-205,ty+37
  3798.   BOX lx+25,ty+45,rx-203,ty+59
  3799.   BOX lx+27,ty+47,rx-205,ty+57
  3800.   BOX lx+25,ty+65,rx-203,by-56
  3801.   BOX lx+27,ty+67,rx-205,ty+77
  3802.   BOX lx+25,by-50,rx-203,by-36
  3803.   BOX lx+27,by-48,rx-205,by-38
  3804.   BOX lx+115,by-20,rx-113,by-6
  3805.   BOX lx+117,by-18,rx-115,by-8
  3806.   TEXT lx+38,ty+35,"1"
  3807.   TEXT lx+38,ty+55,"2"
  3808.   TEXT lx+38,by-60,"3"
  3809.   TEXT lx+38,by-40,"4"
  3810.   TEXT lx+124,by-10,"OK"
  3811.   TEXT lx+68,ty+35,"     Sine Wave     "
  3812.   TEXT lx+68,ty+55,"   Half Sine Wave   "
  3813.   TEXT lx+68,by-60,"    Square Wave    "
  3814.   TEXT lx+68,by-40,"  Half Square Wave  "
  3815.   CLR choice1,choice2,choice3,choice4,choice5
  3816.   REPEAT
  3817.     x=MOUSEX
  3818.     y=MOUSEY
  3819.     k=MOUSEK
  3820.     IF x>lx+27 AND x<rx-205 AND y>ty+27 AND y<ty+37 AND k=1
  3821.       wavform=0
  3822.       IF choice1=1
  3823.         DEFTEXT 1
  3824.         GRAPHMODE 1
  3825.         DEFLINE 1,1
  3826.         DEFFILL 1,2,8
  3827.         PBOX lx+25,ty+25,rx-200,ty+40
  3828.         DEFFILL 0,2,8
  3829.         PBOX lx+25,ty+25,rx-203,ty+39
  3830.         BOX lx+25,ty+25,rx-203,ty+39
  3831.         BOX lx+27,ty+27,rx-205,ty+37
  3832.         TEXT lx+38,ty+35,"1"
  3833.         choice1=0
  3834.       ELSE
  3835.         GRAPHMODE 2
  3836.         choice1=1
  3837.         DEFFILL 0,2,8
  3838.         PBOX lx+25,ty+25,rx-200,ty+40
  3839.         DEFFILL 1,2,8
  3840.         PBOX lx+25,ty+25,rx-203,ty+39
  3841.         DEFLINE 0,1
  3842.         GRAPHMODE 3
  3843.         BOX lx+27,ty+27,rx-205,ty+37
  3844.         DEFTEXT 0
  3845.         TEXT lx+38,ty+35,"1"
  3846.       ENDIF
  3847.     ENDIF
  3848.     IF x>lx+27 AND x<rx-205 AND y>ty+47 AND y<ty+57 AND k=1
  3849.       wavform=2
  3850.       IF choice2=1
  3851.         DEFTEXT 1
  3852.         GRAPHMODE 1
  3853.         DEFLINE 1,1
  3854.         DEFFILL 1,2,8
  3855.         PBOX lx+25,ty+45,rx-200,ty+60
  3856.         DEFFILL 0,2,8
  3857.         PBOX lx+25,ty+45,rx-203,ty+59
  3858.         BOX lx+25,ty+45,rx-203,ty+59
  3859.         BOX lx+27,ty+47,rx-205,ty+57
  3860.         TEXT lx+38,ty+55,"2"
  3861.         choice2=0
  3862.       ELSE
  3863.         GRAPHMODE 2
  3864.         choice2=1
  3865.         DEFFILL 0,2,8
  3866.         PBOX lx+25,ty+45,rx-200,ty+60
  3867.         DEFFILL 1,2,8
  3868.         PBOX lx+25,ty+45,rx-203,ty+59
  3869.         DEFLINE 0,1
  3870.         GRAPHMODE 3
  3871.         BOX lx+27,ty+47,rx-205,ty+57
  3872.         DEFTEXT 0
  3873.         TEXT lx+38,ty+55,"2"
  3874.       ENDIF
  3875.     ENDIF
  3876.     IF x>lx+27 AND x<rx-205 AND y>ty+67 AND y<ty+77 AND k=1
  3877.       wavform=1
  3878.       IF choice3=1
  3879.         DEFTEXT 1
  3880.         GRAPHMODE 1
  3881.         DEFLINE 1,1
  3882.         DEFFILL 1,2,8
  3883.         PBOX lx+25,ty+65,rx-200,by-55
  3884.         DEFFILL 0,2,8
  3885.         PBOX lx+25,ty+65,rx-203,by-56
  3886.         BOX lx+25,ty+65,rx-203,by-56
  3887.         BOX lx+27,ty+67,rx-205,ty+77
  3888.         TEXT lx+38,by-60,"3"
  3889.         choice3=0
  3890.       ELSE
  3891.         GRAPHMODE 2
  3892.         choice3=1
  3893.         DEFFILL 0,2,8
  3894.         PBOX lx+25,ty+65,rx-200,by-55
  3895.         DEFFILL 1,2,8
  3896.         PBOX lx+25,ty+65,rx-203,by-56
  3897.         DEFLINE 0,1
  3898.         GRAPHMODE 3
  3899.         BOX lx+27,ty+67,rx-205,ty+77
  3900.         DEFTEXT 0
  3901.         TEXT lx+38,by-60,"3"
  3902.       ENDIF
  3903.     ENDIF
  3904.     IF x>lx+27 AND x<rx-203 AND y>by-48 AND y<by-28 AND k=1
  3905.       wavform=3
  3906.       IF choice4=1
  3907.         DEFTEXT 1
  3908.         GRAPHMODE 1
  3909.         DEFLINE 1,1
  3910.         DEFFILL 1,2,8
  3911.         PBOX lx+25,by-50,rx-200,by-35
  3912.         DEFFILL 0,2,8
  3913.         PBOX lx+25,by-50,rx-203,by-36
  3914.         BOX lx+25,by-50,rx-203,by-36
  3915.         BOX lx+27,by-48,rx-205,by-38
  3916.         TEXT lx+38,by-40,"4"
  3917.         choice4=0
  3918.       ELSE
  3919.         GRAPHMODE 2
  3920.         choice4=1
  3921.         DEFFILL 0,2,8
  3922.         PBOX lx+25,by-50,rx-200,by-35
  3923.         DEFFILL 1,2,8
  3924.         PBOX lx+25,by-50,rx-203,by-36
  3925.         DEFLINE 0,1
  3926.         GRAPHMODE 3
  3927.         BOX lx+27,by-48,rx-205,by-38
  3928.         DEFTEXT 0
  3929.         TEXT lx+38,by-40,"4"
  3930.       ENDIF
  3931.     ENDIF
  3932.     IF x>lx+117 AND x<rx-115 AND y>by-18 AND y<by-8 AND k=1
  3933.       choice5=1
  3934.     ENDIF
  3935.     PAUSE 10
  3936.   UNTIL choice5<>0
  3937.   PAUSE 5
  3938.   GRAPHMODE 1
  3939.   DEFLINE 1
  3940.   DEFTEXT 1
  3941.   SPUT tempuse$
  3942.   shrinkbox(lx,ty,20,5,lx,ty,rx-lx,by-ty)
  3943.   CLR tempuse$
  3944. RETURN
  3945. '
  3946. PROCEDURE delay_note_on(VAR delay)
  3947.   '
  3948.   lx=190
  3949.   rx=450
  3950.   ty=45
  3951.   by=180
  3952.   '
  3953.   SGET tempuse$
  3954.   GRAPHMODE 1
  3955.   DEFFILL 1,2,2
  3956.   DEFTEXT 1,0,0,6
  3957.   DEFLINE 1,3
  3958.   growbox(lx,ty,10,10,lx,ty,rx-lx,by-ty)
  3959.   PBOX lx,ty,rx,by
  3960.   BOX lx,ty,rx,by
  3961.   DEFLINE 1,1
  3962.   TEXT lx+30,ty+10,"  MIDI Note On Delay:  "
  3963.   DEFFILL 1,2,8
  3964.   PBOX lx+25,ty+25,rx-200,ty+40
  3965.   PBOX lx+25,ty+45,rx-200,ty+60
  3966.   PBOX lx+25,ty+65,rx-200,by-55
  3967.   PBOX lx+25,by-50,rx-200,by-35
  3968.   PBOX lx+115,by-20,rx-110,by-5
  3969.   DEFFILL 0,2,8
  3970.   PBOX lx+25,ty+25,rx-203,ty+39
  3971.   PBOX lx+25,ty+45,rx-203,ty+59
  3972.   PBOX lx+25,ty+65,rx-203,by-56
  3973.   PBOX lx+25,by-50,rx-203,by-36
  3974.   PBOX lx+115,by-20,rx-113,by-6
  3975.   BOX lx+25,ty+25,rx-203,ty+39
  3976.   BOX lx+27,ty+27,rx-205,ty+37
  3977.   BOX lx+25,ty+45,rx-203,ty+59
  3978.   BOX lx+27,ty+47,rx-205,ty+57
  3979.   BOX lx+25,ty+65,rx-203,by-56
  3980.   BOX lx+27,ty+67,rx-205,ty+77
  3981.   BOX lx+25,by-50,rx-203,by-36
  3982.   BOX lx+27,by-48,rx-205,by-38
  3983.   BOX lx+115,by-20,rx-113,by-6
  3984.   BOX lx+117,by-18,rx-115,by-8
  3985.   TEXT lx+38,ty+35,"1"
  3986.   TEXT lx+38,ty+55,"2"
  3987.   TEXT lx+38,by-60,"3"
  3988.   TEXT lx+38,by-40,"4"
  3989.   TEXT lx+124,by-10,"OK"
  3990.   TEXT lx+68,ty+35,"    3 seconds   "
  3991.   TEXT lx+68,ty+55,"    9 seconds   "
  3992.   TEXT lx+68,by-60,"   21 seconds   "
  3993.   TEXT lx+68,by-40,"   30 seconds   "
  3994.   CLR choice1,choice2,choice3,choice4,choice5,delay
  3995.   REPEAT
  3996.     x=MOUSEX
  3997.     y=MOUSEY
  3998.     k=MOUSEK
  3999.     a=MENU(14)
  4000.     b=256
  4001.     IF x>lx+27 AND x<rx-205 AND y>ty+27 AND y<ty+37 AND k=1
  4002.       delay=1
  4003.       IF choice1=1
  4004.         DEFTEXT 1
  4005.         GRAPHMODE 1
  4006.         DEFLINE 1,1
  4007.         DEFFILL 1,2,8
  4008.         PBOX lx+25,ty+25,rx-200,ty+40
  4009.         DEFFILL 0,2,8
  4010.         PBOX lx+25,ty+25,rx-203,ty+39
  4011.         BOX lx+25,ty+25,rx-203,ty+39
  4012.         BOX lx+27,ty+27,rx-205,ty+37
  4013.         TEXT lx+38,ty+35,"1"
  4014.         choice1=0
  4015.       ELSE
  4016.         GRAPHMODE 2
  4017.         choice1=1
  4018.         DEFFILL 0,2,8
  4019.         PBOX lx+25,ty+25,rx-200,ty+40
  4020.         DEFFILL 1,2,8
  4021.         PBOX lx+25,ty+25,rx-203,ty+39
  4022.         DEFLINE 0,1
  4023.         GRAPHMODE 3
  4024.         BOX lx+27,ty+27,rx-205,ty+37
  4025.         DEFTEXT 0
  4026.         TEXT lx+38,ty+35,"1"
  4027.       ENDIF
  4028.     ENDIF
  4029.     IF x>lx+27 AND x<rx-205 AND y>ty+47 AND y<ty+57 AND k=1
  4030.       delay=2
  4031.       IF choice2=1
  4032.         DEFTEXT 1
  4033.         GRAPHMODE 1
  4034.         DEFLINE 1,1
  4035.         DEFFILL 1,2,8
  4036.         PBOX lx+25,ty+45,rx-200,ty+60
  4037.         DEFFILL 0,2,8
  4038.         PBOX lx+25,ty+45,rx-203,ty+59
  4039.         BOX lx+25,ty+45,rx-203,ty+59
  4040.         BOX lx+27,ty+47,rx-205,ty+57
  4041.         TEXT lx+38,ty+55,"2"
  4042.         choice2=0
  4043.       ELSE
  4044.         GRAPHMODE 2
  4045.         choice2=1
  4046.         DEFFILL 0,2,8
  4047.         PBOX lx+25,ty+45,rx-200,ty+60
  4048.         DEFFILL 1,2,8
  4049.         PBOX lx+25,ty+45,rx-203,ty+59
  4050.         DEFLINE 0,1
  4051.         GRAPHMODE 3
  4052.         BOX lx+27,ty+47,rx-205,ty+57
  4053.         DEFTEXT 0
  4054.         TEXT lx+38,ty+55,"2"
  4055.       ENDIF
  4056.     ENDIF
  4057.     IF x>lx+27 AND x<rx-205 AND y>ty+67 AND y<ty+77 AND k=1
  4058.       delay=3
  4059.       IF choice3=1
  4060.         DEFTEXT 1
  4061.         GRAPHMODE 1
  4062.         DEFLINE 1,1
  4063.         DEFFILL 1,2,8
  4064.         PBOX lx+25,ty+65,rx-200,by-55
  4065.         DEFFILL 0,2,8
  4066.         PBOX lx+25,ty+65,rx-203,by-56
  4067.         BOX lx+25,ty+65,rx-203,by-56
  4068.         BOX lx+27,ty+67,rx-205,ty+77
  4069.         TEXT lx+38,by-60,"3"
  4070.         choice3=0
  4071.       ELSE
  4072.         GRAPHMODE 2
  4073.         choice3=1
  4074.         DEFFILL 0,2,8
  4075.         PBOX lx+25,ty+65,rx-200,by-55
  4076.         DEFFILL 1,2,8
  4077.         PBOX lx+25,ty+65,rx-203,by-56
  4078.         DEFLINE 0,1
  4079.         GRAPHMODE 3
  4080.         BOX lx+27,ty+67,rx-205,ty+77
  4081.         DEFTEXT 0
  4082.         TEXT lx+38,by-60,"3"
  4083.       ENDIF
  4084.     ENDIF
  4085.     IF x>lx+27 AND x<rx-203 AND y>by-48 AND y<by-28 AND k=1
  4086.       delay=4
  4087.       IF choice4=1
  4088.         DEFTEXT 1
  4089.         GRAPHMODE 1
  4090.         DEFLINE 1,1
  4091.         DEFFILL 1,2,8
  4092.         PBOX lx+25,by-50,rx-200,by-35
  4093.         DEFFILL 0,2,8
  4094.         PBOX lx+25,by-50,rx-203,by-36
  4095.         BOX lx+25,by-50,rx-203,by-36
  4096.         BOX lx+27,by-48,rx-205,by-38
  4097.         TEXT lx+38,by-40,"4"
  4098.         choice4=0
  4099.       ELSE
  4100.         GRAPHMODE 2
  4101.         choice4=1
  4102.         DEFFILL 0,2,8
  4103.         PBOX lx+25,by-50,rx-200,by-35
  4104.         DEFFILL 1,2,8
  4105.         PBOX lx+25,by-50,rx-203,by-36
  4106.         DEFLINE 0,1
  4107.         GRAPHMODE 3
  4108.         BOX lx+27,by-48,rx-205,by-38
  4109.         DEFTEXT 0
  4110.         TEXT lx+38,by-40,"4"
  4111.       ENDIF
  4112.     ENDIF
  4113.     IF x>lx+117 AND x<rx-115 AND y>by-18 AND y<by-8 AND k=1
  4114.       choice5=1
  4115.     ENDIF
  4116.     PAUSE 10
  4117.   UNTIL choice5<>0
  4118.   PAUSE 5
  4119.   IF delay=0
  4120.     delay=1
  4121.   ENDIF
  4122.   GRAPHMODE 1
  4123.   DEFLINE 1
  4124.   DEFTEXT 1
  4125.   SPUT tempuse$
  4126.   shrinkbox(lx,ty,20,5,lx,ty,rx-lx,by-ty)
  4127.   CLR tempuse$
  4128. RETURN
  4129. '
  4130. PROCEDURE popup_audition(pitch)
  4131.   lx=124
  4132.   rx=516
  4133.   ty=64
  4134.   by=84
  4135.   '
  4136.   '
  4137.   IF rez=2
  4138.     offset=10
  4139.     ty=ty-10
  4140.     by=by+10
  4141.   ENDIF
  4142.   SGET tempuse$
  4143.   DEFFILL 0,2,8
  4144.   IF rez=2
  4145.     DEFTEXT 1,0,0,13
  4146.   ELSE
  4147.     DEFTEXT 1,0,0,6
  4148.   ENDIF
  4149.   DEFLINE 1,3
  4150.   growbox(lx,ty,10,10,lx,ty,rx-lx,by-ty)
  4151.   PBOX lx,ty,rx,by
  4152.   BOX lx,ty,rx,by
  4153.   DEFLINE 1,1
  4154.   BOX lx+8,ty+2,rx-8,by-2
  4155.   IF rez=2
  4156.     IF pitch=1
  4157.       TEXT lx+35,ty+4+9+offset,"Auditioning Patch Sound Bank(low pitch)"
  4158.     ENDIF
  4159.     IF pitch=2
  4160.       TEXT lx+35,ty+4+9+offset,"Auditioning Patch Sound Bank(medium pitch)"
  4161.     ENDIF
  4162.     IF pitch=3
  4163.       TEXT lx+35,ty+4+9+offset,"Auditioning Patch Sound Bank(high pitch)"
  4164.     ENDIF
  4165.   ELSE
  4166.     IF pitch=1
  4167.       TEXT lx+35,ty+4+9,"Auditioning Patch Sound Bank(low pitch)"
  4168.     ENDIF
  4169.     IF pitch=2
  4170.       TEXT lx+35,ty+4+9,"Auditioning Patch Sound Bank(medium pitch)"
  4171.     ENDIF
  4172.     IF pitch=3
  4173.       TEXT lx+35,ty+4+9,"Auditioning Patch Sound Bank(high pitch)"
  4174.     ENDIF
  4175.   ENDIF
  4176.   SELECT midi_delay
  4177.   CASE 1
  4178.     DELAY 1                         !Delay 1 second between notes
  4179.   CASE 2
  4180.     DELAY 3                         !Delay 3 seconds between notes
  4181.   CASE 3
  4182.     DELAY 7                         !Delay 7 seconds between notes
  4183.   CASE 4
  4184.     DELAY 10                        !Delay 10 seconds between notes
  4185.   ENDSELECT
  4186.   '
  4187.   SPUT tempuse$
  4188.   CLR tempuse$
  4189.   PAUSE 5
  4190.   shrinkbox(lx,ty,20,5,lx,ty,rx-lx,by-ty)
  4191. RETURN
  4192. '
  4193. ' ***********************************************************************
  4194. ' THE FOLLOWING ROUTINES DISPLAY ONLINE HELP FOR MOST PROGRAM FUNCTIONS
  4195. ' IN THE FORM OF POP-UP BOXES.
  4196. ' ***********************************************************************
  4197. '
  4198. PROCEDURE about_general
  4199.   '
  4200.   lx=94
  4201.   rx=575
  4202.   ty=14
  4203.   by=175
  4204.   '
  4205.   DIM helpbox$(47)
  4206.   helpbox$(1)="Welcome to the Yamaha Patch Editor/Librarian for"
  4207.   helpbox$(2)="the PSS Portasound Series.  This help section"
  4208.   helpbox$(3)="will provide basic information on GEM menu commands"
  4209.   helpbox$(4)="and also provide an understanding of the System"
  4210.   helpbox$(5)="Exclusive (SYSEX) MIDI data that is supported with"
  4211.   helpbox$(6)="this keyboard instrument."
  4212.   helpbox$(7)=""
  4213.   helpbox$(8)="Your Yamaha keyboard instrument consists of highly"
  4214.   helpbox$(9)="complex digital tone generator components that are"
  4215.   helpbox$(10)="capable of producing a multitude of voice instru-"
  4216.   helpbox$(11)="ments which may be stored in any of five voice"
  4217.   helpbox$(12)="banks. A total of 100 voices are permanently stored"
  4218.   helpbox$(13)="in the instrument and were all preset at the factory."
  4219.   helpbox$(14)="An on board digital synthesizer allows you to edit"
  4220.   helpbox$(15)="any voice instrument which can be stored in the voice"
  4221.   helpbox$(16)="banks without any MIDI capability."
  4222.   helpbox$(17)=""
  4223.   helpbox$(18)="This program is designed to easily assist you in cre-"
  4224.   helpbox$(19)="ating/editing/modifying any instrument voice (patch)."
  4225.   helpbox$(20)="The power of the MIDI interface allows the use of a"
  4226.   helpbox$(21)="computer to control 'patch editing' at a much higher"
  4227.   helpbox$(22)="level.  Your Yamaha keyboard instrument provides only"
  4228.   helpbox$(23)="basic editing capabilities in modifying an internal"
  4229.   helpbox$(24)="voice, however, there are limitations.  This program"
  4230.   helpbox$(25)="introduces several editing capabilities that cannot"
  4231.   helpbox$(26)="be performed with the on board digital synthesizer."
  4232.   helpbox$(27)="In addition, it is convenient to easily load and save"
  4233.   helpbox$(28)="all patches to/from disk.  With the aid of the LHA"
  4234.   helpbox$(29)="archiving utility, the program is complemented with"
  4235.   helpbox$(30)="a simple librarian interface, complete with patch de-"
  4236.   helpbox$(31)="scription capability (comments) and easy retrieval of"
  4237.   helpbox$(32)="stored patches in the system archive file, PATCHES.LZH"
  4238.   helpbox$(33)=""
  4239.   helpbox$(34)="The SYSEX messages within the Yamaha keyboard"
  4240.   helpbox$(35)="instrument consist of the 5 voice banks, Song Memory"
  4241.   helpbox$(36)="(both melody 1-5 and chord 1-5), and the Custom"
  4242.   helpbox$(37)="Drummer.  It is the Song Memory itself which makes"
  4243.   helpbox$(38)="up most of the SYSEX data (over 12 Kbytes) and"
  4244.   helpbox$(39)="PSSLIB currently supports everything but this for now."
  4245.   helpbox$(40)=""
  4246.   helpbox$(41)="The rest of this help section provides basic program"
  4247.   helpbox$(42)="operation and definitions of all patch editing para-"
  4248.   helpbox$(43)="meters.  All parameters that effect the Modulator will"
  4249.   helpbox$(44)="basically effect the tonal quality of the sound patch."
  4250.   helpbox$(45)="All parameters that effect the Carrier will basically"
  4251.   helpbox$(46)="effect the overall sound quality as well as the volume"
  4252.   helpbox$(47)="of the sound patch."
  4253.   lineno=DIM?(helpbox$())
  4254.   do_helpbox
  4255.   ERASE helpbox$()
  4256.   VOID FRE(0)
  4257.   PAUSE 20
  4258.   '
  4259. RETURN
  4260. '
  4261. PROCEDURE about_file
  4262.   '
  4263.   lx=124
  4264.   rx=516
  4265.   ty=14
  4266.   by=175
  4267.   '
  4268.   DIM helpbox$(36)
  4269.   helpbox$(1)="Load Patch - loads a patch from the system"
  4270.   helpbox$(2)="archive file into memory. Use the standard"
  4271.   helpbox$(3)="item selector to select the desired patch"
  4272.   helpbox$(4)="sound.  PSSLIB will prompt you if the patch"
  4273.   helpbox$(5)="doesn't exist within the archive, in which"
  4274.   helpbox$(6)="case, you may select a correct existing one."
  4275.   helpbox$(7)="Use the Verbose option to get a current"
  4276.   helpbox$(8)="listing of all valid patch names."
  4277.   helpbox$(9)=""
  4278.   helpbox$(10)="Save Patch - saves a patch from memory to"
  4279.   helpbox$(11)="the system archive file.  You may use up "
  4280.   helpbox$(12)="to 50 characters to describe the patch "
  4281.   helpbox$(13)="sound.  Enter a new patch name via the "
  4282.   helpbox$(14)="standard item selector. You may also"
  4283.   helpbox$(15)="export the patch to be used with other "
  4284.   helpbox$(16)="MIDI programs, if desired. The file will"
  4285.   helpbox$(17)="saved with a .SYX extension."
  4286.   helpbox$(18)=""
  4287.   helpbox$(19)="Delete Patch - deletes a patch from the "
  4288.   helpbox$(20)="system archive file.  Use the standard"
  4289.   helpbox$(21)="item selector to permanently delete the"
  4290.   helpbox$(22)="patch sound from the system archive."
  4291.   helpbox$(23)="                     "
  4292.   helpbox$(24)="Build Patch - clears the MIDI patch buffer"
  4293.   helpbox$(25)="and allows you to build up a sound in"
  4294.   helpbox$(26)="segments via each MIDI parameter group."
  4295.   helpbox$(27)=""
  4296.   helpbox$(28)="Verbose Directory - displays a listing of"
  4297.   helpbox$(29)="all patch sounds within the system archive"
  4298.   helpbox$(30)="file.  Use CNTL/S and CNTL/Q to halt the"
  4299.   helpbox$(31)="screen display while viewing the list. When"
  4300.   helpbox$(32)="the list is done, press any key to return"
  4301.   helpbox$(33)="to the GEM menus."
  4302.   helpbox$(34)=""
  4303.   helpbox$(35)="Quit - Quits the program and returns to "
  4304.   helpbox$(36)="the GEM desktop"
  4305.   lineno=DIM?(helpbox$())
  4306.   do_helpbox
  4307.   ERASE helpbox$()
  4308.   VOID FRE(0)
  4309.   PAUSE 20
  4310.   '
  4311. RETURN
  4312. '
  4313. PROCEDURE about_buffer
  4314.   '
  4315.   lx=124
  4316.   rx=550
  4317.   ty=14
  4318.   by=175
  4319.   '
  4320.   DIM helpbox$(17)
  4321.   helpbox$(1)="View Parameters - displays all current MIDI"
  4322.   helpbox$(2)="Patch Parameters in memory.  There are 3"
  4323.   helpbox$(3)="columns showing the Overall Modulation,"
  4324.   helpbox$(4)="Modulator characteristics, and Carrier charac-"
  4325.   helpbox$(5)="teristics of the patch sound."
  4326.   helpbox$(6)=""
  4327.   helpbox$(7)="View Buffer - displays all current MIDI Patch"
  4328.   helpbox$(8)="Parameters in memory in hexadecimal format."
  4329.   helpbox$(9)="This is how they appear when being sent or re-"
  4330.   helpbox$(10)="ceived from the Yamaha keyboard instrument. The"
  4331.   helpbox$(11)="current patch file name will also appear if it"
  4332.   helpbox$(12)="was just previously loaded from disk."
  4333.   helpbox$(13)="Note: The View Parameters mode is the default"
  4334.   helpbox$(14)="viewing mode. Selecting a viewing mode from the"
  4335.   helpbox$(15)="GEM menu will toggle between the two modes. You"
  4336.   helpbox$(16)="may also use this function to guarantee that all"
  4337.   helpbox$(17)="menu selections are available."
  4338.   lineno=DIM?(helpbox$())
  4339.   do_helpbox
  4340.   ERASE helpbox$()
  4341.   VOID FRE(0)
  4342.   PAUSE 20
  4343.   '
  4344. RETURN
  4345. '
  4346. PROCEDURE about_midi
  4347.   '
  4348.   lx=94
  4349.   rx=555
  4350.   ty=14
  4351.   by=175
  4352.   '
  4353.   DIM helpbox$(80)
  4354.   helpbox$(1)="Send Bank (1 - 5) - sends the current patch buffer"
  4355.   helpbox$(2)="in memory to the patch bank of the Yamaha keyboard"
  4356.   helpbox$(3)="instrument based on the menu selection. The "
  4357.   helpbox$(4)="instrument will auto-switch to the selected bank as"
  4358.   helpbox$(5)="long as it is in Voice mode.  An ERR will be dis-"
  4359.   helpbox$(6)="played on the Yamaha keyboard instrument for any MIDI"
  4360.   helpbox$(7)="transmission errors."
  4361.   helpbox$(8)=""
  4362.   helpbox$(9)="Receive Bank (1 - 5) - receives a patch bank from the"
  4363.   helpbox$(10)="Yamaha keyboard instrument and places it into memory."
  4364.   helpbox$(11)="Two alert boxes are shown to allow you to prepare the"
  4365.   helpbox$(12)="keyboard for transmission via the Memory Bulk Dump."
  4366.   helpbox$(13)="After responding to the alert boxes, the monitor "
  4367.   helpbox$(14)="screen will note that a 512 byte MIDI transmission"
  4368.   helpbox$(15)="buffer was established.  At the middle of the screen,"
  4369.   helpbox$(16)="the message,'Waiting for MIDI.....' indicates that"
  4370.   helpbox$(17)="you may now perform the bulk dump.  Press the"
  4371.   helpbox$(18)="'TRANSMIT CH./MEMORY BULK DUMP' twice (Note: the"
  4372.   helpbox$(19)="display LED's will flash) and press the '+' button"
  4373.   helpbox$(20)="once.  The bottom of the screen will indicate that"
  4374.   helpbox$(21)="MIDI data is being received.  After reception, it"
  4375.   helpbox$(22)="will indicate the bank that was received. There will"
  4376.   helpbox$(23)="be a slight delay to allow the rest of the bulk dump"
  4377.   helpbox$(24)="to occur.  The Yamaha keyboard instrument will now"
  4378.   helpbox$(25)="auto-switch to the selected received bank and the "
  4379.   helpbox$(26)="current viewing mode will be displayed."
  4380.   helpbox$(27)=""
  4381.   helpbox$(28)="Import Custom Drummer/.SYX - loads and sends a .SYX"
  4382.   helpbox$(29)="file via the standard file selector. If the file is"
  4383.   helpbox$(30)="a voice patch (72 bytes), the patch will be routed"
  4384.   helpbox$(31)="to the bank defined within the file (it is best to"
  4385.   helpbox$(32)="name these with a 1-5 to match the corresponding"
  4386.   helpbox$(33)="bank number). AN ERR will appear on the Yamaha if"
  4387.   helpbox$(34)="a MIDI transmission error occurred.  If the Yamaha"
  4388.   helpbox$(35)="is already in Keyboard Assign mode [c.00], the"
  4389.   helpbox$(36)="Custom Drummer will auto play if it is turned on,"
  4390.   helpbox$(37)="otherwise, the current Rhythm Style will play since"
  4391.   helpbox$(38)="this selection issues MIDI Start/MIDI Stop commands"
  4392.   helpbox$(39)="which turns the drum machine either on or off."
  4393.   helpbox$(40)=""
  4394.   helpbox$(41)="Export Custom Drummer - receives and saves the Custom"
  4395.   helpbox$(42)="Drummer Info to disk.  Do a Memory BULK DUMP on the"
  4396.   helpbox$(43)="synthesizer the same as receiving a bank. The System"
  4397.   helpbox$(44)="MIDI buffer will be changed to 13800 bytes since this"
  4398.   helpbox$(45)="is the last message to be received. (It may also take"
  4399.   helpbox$(46)="up to 20 seconds or so, be patient!) Then, save it to"
  4400.   helpbox$(47)="it to disk via the standard file selector."
  4401.   helpbox$(48)=""
  4402.   helpbox$(49)="Audition - selecting this option will allow you to"
  4403.   helpbox$(50)="play 3 notes (low C, middle C, high C) when issuing"
  4404.   helpbox$(51)="any MIDI Send command, which includes importing a"
  4405.   helpbox$(52)=".SYX file.  A dialog box will allow you 4 choices"
  4406.   helpbox$(53)="for defining a MIDI Delay Value:"
  4407.   helpbox$(54)=""
  4408.   helpbox$(55)=" 3 seconds ( 1 sec between each note)"
  4409.   helpbox$(56)=" 9 seconds ( 3 sec between each note)"
  4410.   helpbox$(57)="21 seconds ( 7 sec between each note)"
  4411.   helpbox$(58)="30 seconds (10 sec bewteen each note)"
  4412.   helpbox$(59)=""
  4413.   helpbox$(60)="The purpose of auditioning is to aid in selecting"
  4414.   helpbox$(61)="the right combination of patch parameters before"
  4415.   helpbox$(62)="saving.  It is also convenient if your keyboard"
  4416.   helpbox$(63)="is not close to your computer. The 3 C notes used"
  4417.   helpbox$(64)="at different pitches should help especially with"
  4418.   helpbox$(65)="AM sounds and Level Key Scaling (See Modulator/"
  4419.   helpbox$(66)="Carrier). Once a delay value is specified, when"
  4420.   helpbox$(67)="you issue any MIDI Send command, a popup dialog"
  4421.   helpbox$(68)="will indicate the Low, Medium and High values"
  4422.   helpbox$(69)="when they are sent."
  4423.   helpbox$(70)=""
  4424.   helpbox$(71)="Continually selecting the Audition option will"
  4425.   helpbox$(72)="toggle the Audition Mode, that is, it turns on"
  4426.   helpbox$(73)="and off indicated by a checkmark in front of the"
  4427.   helpbox$(74)="option menu."
  4428.   helpbox$(75)=""
  4429.   helpbox$(76)=""
  4430.   helpbox$(77)="Note: All of these MIDI functions will not be"
  4431.   helpbox$(78)="initially selectable either if the Yamaha keyboard "
  4432.   helpbox$(79)="instrument is turned off or not plugged into the ST "
  4433.   helpbox$(80)="via the proper MIDI chords."
  4434.   lineno=DIM?(helpbox$())
  4435.   do_helpbox
  4436.   ERASE helpbox$()
  4437.   VOID FRE(0)
  4438.   PAUSE 20
  4439.   '
  4440. RETURN
  4441. '
  4442. PROCEDURE about_modulation
  4443.   '
  4444.   lx=94
  4445.   rx=555
  4446.   ty=14
  4447.   by=175
  4448.   '
  4449.   DIM helpbox$(55)
  4450.   helpbox$(1)="This patch parameter group is used to effect the"
  4451.   helpbox$(2)="overall modulation of a patch sound.  It is divided"
  4452.   helpbox$(3)="into 2 subgroups: Leveling and AM/FM Functions."
  4453.   helpbox$(4)=""
  4454.   helpbox$(5)="Leveling - use this to enter all modulation leveling"
  4455.   helpbox$(6)="functions via the mouse buttons."
  4456.   helpbox$(7)=""
  4457.   helpbox$(8)="Modulation Level - use this to increase or decrease"
  4458.   helpbox$(9)="the Modulator's overall volume effect on the Carrier"
  4459.   helpbox$(10)="signal.  The allowable range is from 0 to 99."
  4460.   helpbox$(11)=""
  4461.   helpbox$(12)=""
  4462.   helpbox$(13)="Total Level - use this to increase or decrease the"
  4463.   helpbox$(14)="Carrier signal's volume, which will effectively"
  4464.   helpbox$(15)="change the total patch sound volume.  The allowable"
  4465.   helpbox$(16)="range is from 0 to 99."
  4466.   helpbox$(17)=""
  4467.   helpbox$(18)="Feedback Level - use this to increase or decrease"
  4468.   helpbox$(19)="how much the Modulator signal modulates itself. The"
  4469.   helpbox$(20)="allowable range is from 0 to 7."
  4470.   helpbox$(21)=""
  4471.   helpbox$(22)="AM/FM - use this to enter any Amplitude Modulation"
  4472.   helpbox$(23)="and/or Frequency Modulation functions to the patch"
  4473.   helpbox$(24)="sound via the mouse buttons."
  4474.   helpbox$(25)="AM Sensitivity - use this to increase or decrease"
  4475.   helpbox$(26)="the amount of 'warble' to the patch sound.  It will"
  4476.   helpbox$(27)="only take effect when AM is enabled on either the"
  4477.   helpbox$(28)="Modulator or the Carrier or both.  The allowable"
  4478.   helpbox$(29)="range is from 0 to 3."
  4479.   helpbox$(30)=""
  4480.   helpbox$(31)="FM enable - use this to toggle the Vibrato effect"
  4481.   helpbox$(32)="of the patch sound.  When 'ON', the Vibrato LED"
  4482.   helpbox$(33)="under 'EFFECT' of the Yamaha keyboard instrument"
  4483.   helpbox$(34)="should be lit."
  4484.   helpbox$(35)=""
  4485.   helpbox$(36)=""
  4486.   helpbox$(37)="FM Sensitivity - use this to increase or decrease"
  4487.   helpbox$(38)="the amount of Vibrato used when FM is enabled. This"
  4488.   helpbox$(39)="also effects the overall 'pitch warble' of the "
  4489.   helpbox$(40)="patch sound and is also referred to as the Pitch"
  4490.   helpbox$(41)="Modulation Sensitivity.  The allowable range is"
  4491.   helpbox$(42)="from 0 to 7."
  4492.   helpbox$(43)=""
  4493.   helpbox$(44)="FM Delay Time - use this to increase or decrease "
  4494.   helpbox$(45)="a time interval from when a note is pressed to when"
  4495.   helpbox$(46)="the Vibrato will take effect when FM is enabled."
  4496.   helpbox$(47)="The allowable range is from 0 to 127."
  4497.   helpbox$(48)=""
  4498.   helpbox$(49)="Sustain Enable - use this to toggle the Sustain"
  4499.   helpbox$(50)="effect of the patch sound.  When 'ON', the"
  4500.   helpbox$(51)="Sustain LED under 'EFFECT' of the Yamaha keyboard"
  4501.   helpbox$(52)="instrument should be lit.  This function will"
  4502.   helpbox$(53)="allow the Sustain Release Rate to override the"
  4503.   helpbox$(54)="standard Release Rate in the Envelope parameter"
  4504.   helpbox$(55)="group."
  4505.   lineno=DIM?(helpbox$())
  4506.   do_helpbox
  4507.   ERASE helpbox$()
  4508.   VOID FRE(0)
  4509.   PAUSE 20
  4510.   '
  4511. RETURN
  4512. '
  4513. PROCEDURE about_mod_car
  4514.   '
  4515.   lx=94
  4516.   rx=555
  4517.   ty=14
  4518.   by=175
  4519.   '
  4520.   DIM helpbox$(111)
  4521.   helpbox$(1)="These patch parameter groups modify certain aspects"
  4522.   helpbox$(2)="of the Modulator signal and the Carrier signal de-"
  4523.   helpbox$(3)="pending on which item is selected. There are 5 "
  4524.   helpbox$(4)="subgroups pertaining to each signal."
  4525.   helpbox$(5)=""
  4526.   helpbox$(6)="Define Waveform - Selecting this function will cause"
  4527.   helpbox$(7)="a standard radio box to appear allowing you to select"
  4528.   helpbox$(8)="the shape of the signal.  There are 4 choices which"
  4529.   helpbox$(9)="include Sine Wave, Half Sine Wave, Square Wave, and"
  4530.   helpbox$(10)="Half Square Wave (Note: a Square Wave translates to"
  4531.   helpbox$(11)="a Squared Sine Wave).  Clicking on OK after choosing"
  4532.   helpbox$(12)="a shape will return to the GEM menu."
  4533.   helpbox$(13)="Tuning - use this to allow for editing all detuning"
  4534.   helpbox$(14)="functions associated with each signal via the mouse"
  4535.   helpbox$(15)="buttons."
  4536.   helpbox$(16)=""
  4537.   helpbox$(17)="Fine Detune - use this to finely increase or decrease"
  4538.   helpbox$(18)="the signal's pitch.  A positive number will make"
  4539.   helpbox$(19)="the pitch sound sharper, a negative number will make"
  4540.   helpbox$(20)="the pitch sound flatter. The allowable range is from"
  4541.   helpbox$(21)="-7 to +7."
  4542.   helpbox$(22)=""
  4543.   helpbox$(23)="Course Detune - use this to cause the signal's pitch"
  4544.   helpbox$(24)="to become way out of tune. It is either OFF or ON."
  4545.   helpbox$(25)="Frequency Multiplier - use this to increase or"
  4546.   helpbox$(26)="decrease the frequency of the signal.  A value of"
  4547.   helpbox$(27)="1 is equivalent to the standard pitch of the signal."
  4548.   helpbox$(28)="Doubling the value will raise the pitch by 1 octave."
  4549.   helpbox$(29)="Setting the value to 0 will lower the standard"
  4550.   helpbox$(30)="pitch of the signal by 1 octave. The allowable"
  4551.   helpbox$(31)="range is from 0 to 15."
  4552.   helpbox$(32)=""
  4553.   helpbox$(33)="LKS/RKS - use this to allow the editing of Level Key"
  4554.   helpbox$(34)="Scaling and Rate Key Scaling functions associated"
  4555.   helpbox$(35)="with each signal via the mouse buttons."
  4556.   helpbox$(36)=""
  4557.   helpbox$(37)="Level Key Scale Hi/Lo - use both of these functions"
  4558.   helpbox$(38)="to increase or decrease the volume of each signal as"
  4559.   helpbox$(39)="you go up or down the keyboard scale.  The MIDI note"
  4560.   helpbox$(40)="[C3] or middle C has no effect.  LKS Lo effects all"
  4561.   helpbox$(41)="notes below C3 and LKS Hi effects all notes above"
  4562.   helpbox$(42)="C3.  A value of 0 on both functions turns Level Key"
  4563.   helpbox$(43)="Scaling off.  The allowable range for both functions"
  4564.   helpbox$(44)="is from 0 to 15. Low values on LKS Lo will moder-"
  4565.   helpbox$(45)="ately decrease the volume as you approach C3. As you"
  4566.   helpbox$(46)="increase the value, the volume will decrease less "
  4567.   helpbox$(47)="and less until you reach 8. Now, high values on LKS"
  4568.   helpbox$(48)="Lo will moderately increase the volume as you "
  4569.   helpbox$(49)="approach C3 and as you decrease this value, the"
  4570.   helpbox$(50)="volume will increase less and less until you reach 8."
  4571.   helpbox$(51)=""
  4572.   helpbox$(52)="LKS Hi works quite differently. Bear in mind that"
  4573.   helpbox$(53)="since the frequency's signal is higher above C3, the"
  4574.   helpbox$(54)="overall volume effect is less noticeable. Values"
  4575.   helpbox$(55)="1 thru 3 will slightly increase the volume from C3"
  4576.   helpbox$(56)="onward with 1 being the most noticeable."
  4577.   helpbox$(57)="Values 4 thru 10 will slightly decrease the volume"
  4578.   helpbox$(58)="from C3 onward in a linear fashion with 10 being"
  4579.   helpbox$(59)="the most noticeable. Values 11 thru 15 will slightly"
  4580.   helpbox$(60)="decrease the volume from C3 onward in more of an"
  4581.   helpbox$(61)="exponential fashion with 15 being the most no-."
  4582.   helpbox$(62)="ticeable."
  4583.   helpbox$(63)=""
  4584.   helpbox$(64)="The Level Key Scale function works best with the"
  4585.   helpbox$(65)="Frequency Mulitplier set to very low values."
  4586.   helpbox$(66)=""
  4587.   helpbox$(67)="Rate Key Scale - use this to increase or decrease"
  4588.   helpbox$(68)="the rate of the signal's attack and decay functions."
  4589.   helpbox$(69)="As you move up the keyboard scale, this effect will"
  4590.   helpbox$(70)="cause the attack and decay to become more rapid at"
  4591.   helpbox$(71)="high values.  The allowable range is from 0 to 3."
  4592.   helpbox$(72)=""
  4593.   helpbox$(73)="Enveloping - use this to allow for editing all"
  4594.   helpbox$(74)="envelope functions to the signal via the mouse"
  4595.   helpbox$(75)="buttons."
  4596.   helpbox$(76)=""
  4597.   helpbox$(77)="Attack Rate - use this to increase or decrease the"
  4598.   helpbox$(78)="rate at which the signal will build up to its highest"
  4599.   helpbox$(79)="peak level.  The allowable range is from 0 - 63."
  4600.   helpbox$(80)=""
  4601.   helpbox$(81)="Decay 1 Rate - once the signal is at its highest peak"
  4602.   helpbox$(82)="level, use this to increase or decrease the amount of"
  4603.   helpbox$(83)="time it takes for the signal to fade off while con-"
  4604.   helpbox$(84)="tinuously holding down the note on the keyboard "
  4605.   helpbox$(85)="instrument. The allowable range is from 0 to 63."
  4606.   helpbox$(86)=""
  4607.   helpbox$(87)="Decay 1 Level - this defines the 1st volume level at"
  4608.   helpbox$(88)="which the signal will drop from highest peak.  The "
  4609.   helpbox$(89)="allowable range is from 0 to 15."
  4610.   helpbox$(90)=""
  4611.   helpbox$(91)="Decay 2 Rate - once the signal has reached the decay"
  4612.   helpbox$(92)="1 level, use this to control the time it takes for"
  4613.   helpbox$(93)="the signal to finally fade off to silence while "
  4614.   helpbox$(94)="holding down the note on the keyboard instrument."
  4615.   helpbox$(95)="The allowable range is from 0 to 63."
  4616.   helpbox$(96)=""
  4617.   helpbox$(97)="Release Rate - use this to increase or decrease the"
  4618.   helpbox$(98)="rate at which the sound fades off to silence when"
  4619.   helpbox$(99)="releasing the note on the keyboard instrument. This"
  4620.   helpbox$(100)="will only occur when both the Decay 1/Decay 2"
  4621.   helpbox$(101)="rates are set at low values and when Sustain is"
  4622.   helpbox$(102)="off (under AM/FM).  The allowable range is from"
  4623.   helpbox$(103)="0 to 15."
  4624.   helpbox$(104)=""
  4625.   helpbox$(105)="Sustain Release Rate - this replaces the Release"
  4626.   helpbox$(106)="Rate when Sustain is turned on via AM/FM control."
  4627.   helpbox$(107)="The allowable range is from 0 to 15."
  4628.   helpbox$(109)="AM Enable - use this to toggle the Amplitude "
  4629.   helpbox$(110)="Modulation for each signal and allow the 'warble'"
  4630.   helpbox$(111)="to take effect in AM Sensitivity."
  4631.   lineno=DIM?(helpbox$())
  4632.   do_helpbox
  4633.   ERASE helpbox$()
  4634.   VOID FRE(0)
  4635.   PAUSE 20
  4636.   '
  4637. RETURN
  4638. '
  4639. PROCEDURE do_helpbox
  4640.   '
  4641.   HIDEM
  4642.   CLR offset
  4643.   SGET tempuse$         !Save screen
  4644.   CLS
  4645.   MENU m$()             !show GEM Menus
  4646.   DEFFILL 0,2,8
  4647.   IF rez=1
  4648.     DEFTEXT 1,0,0,6     !define screen font
  4649.   ELSE
  4650.     lx=lx-70            !redefine for monochrome display
  4651.     rx=rx-70
  4652.     ty=ty+50
  4653.     by=by+161
  4654.     offset=10
  4655.     DEFTEXT 1,0,0,13
  4656.   ENDIF
  4657.   growbox(lx,ty,10,10,lx,ty,rx-lx,by-ty)  !Make pop-up box
  4658.   PBOX lx,ty,rx,by
  4659.   DEFLINE 1,3
  4660.   BOX lx,ty,rx,by
  4661.   DEFLINE 1,1
  4662.   BOX lx+8,ty+2,rx-8,by-2
  4663.   IF rez=1
  4664.     TEXT lx+12,by-5,"Left-{Page Down}|Right-{Page Up}|Both-Exit"
  4665.   ELSE
  4666.     TEXT lx+90,by+20,"Left-{Page Down}|Right-{Page Up}|Both-Exit"
  4667.   ENDIF
  4668.   '
  4669.   pointer=1                     ! initialize page pointer
  4670.   pages=INT((lineno-1)/12)      ! define 12 lines per page
  4671.   overflow=(lineno-1) MOD 12    ! define overflow flag
  4672.   IF overflow>0
  4673.     pages=pages+1               ! increment page for over 12 lines
  4674.   ENDIF
  4675.   drawlines                     ! draw the page
  4676.   DO
  4677.     m=MOUSEK
  4678.     KEYTEST key
  4679.     IF m=2 OR ((key=4915200) OR (key=273350656)) !Left arrow or right mouse
  4680.       IF pointer>1
  4681.         DEC pointer             !decrement pointer
  4682.         drawlines               !draw previous page
  4683.       ENDIF
  4684.     ELSE
  4685.       pointer=pointer
  4686.     ENDIF
  4687.     IF m=1 OR ((key=5046272) OR (key=273481728)) !Right arrow or left mouse
  4688.       IF pointer<pages
  4689.         INC pointer             !increment pointer
  4690.         drawlines               !draw next page
  4691.       ELSE
  4692.         pointer=pointer
  4693.       ENDIF
  4694.     ENDIF
  4695.     EXIT IF m=3 OR (key=6356992 OR key=274792448) !UNDO or both
  4696.   LOOP
  4697.   SPUT tempuse$                 !get previous screen
  4698.   CLR tempuse$,offset
  4699.   shrinkbox(lx,ty,20,5,lx,ty,rx-lx,by-ty) ! Undo pop-up box
  4700.   DEFTEXT 1,0,0,10              !reinitialize screen font
  4701.   '
  4702. RETURN
  4703. '
  4704. PROCEDURE drawlines
  4705.   '
  4706.   PBOX lx+10,ty+6,rx-11,by-15
  4707.   startloop=(pointer*12)-12
  4708.   FOR drawlines=1 TO 12
  4709.     EXIT IF drawlines+startloop>lineno-1
  4710.     TEXT lx+26,(ty+11)+10*drawlines+(offset*drawlines),helpbox$(startloop+drawlines)
  4711.   NEXT drawlines
  4712.   IF pointer>9 THEN
  4713.     IF rez=1
  4714.       TEXT 30,30,"       "
  4715.       TEXT 30,30,"Page "+STR$(pointer)
  4716.     ELSE
  4717.       TEXT 30,35,"       "
  4718.       TEXT 30,35,"Page "+STR$(pointer)
  4719.     ENDIF
  4720.   ELSE
  4721.     IF pointer<10 THEN
  4722.       IF rez=1
  4723.         TEXT 30,30,"       "
  4724.         TEXT 30,30,"Page "+STR$(pointer)
  4725.       ELSE
  4726.         TEXT 30,35,"       "
  4727.         TEXT 30,35,"Page "+STR$(pointer)
  4728.       ENDIF
  4729.     ELSE
  4730.       TEXT 30,30,"Page "+STR$(pointer)
  4731.     ENDIF
  4732.   ENDIF
  4733.   IF rez=1
  4734.     TEXT 40,40,"of "+STR$(pages)
  4735.   ELSE
  4736.     TEXT 40,55,"of "+STR$(pages)
  4737.   ENDIF
  4738. RETURN
  4739. ' These are the GEM™ GRAF_GROWBOX & GRAF_SHRINKBOX Routines
  4740. ' Init stands for Initial(X,Y,Height) and Fin stands for Final(X,Y,Height)
  4741. '
  4742. PROCEDURE growbox(init_x%,init_y%,init_w%,init_h%,fin_x%,fin_y%,fin_w%,fin_h%)
  4743.   '
  4744.   DPOKE GINTIN,init_x%
  4745.   DPOKE GINTIN+2,init_y%
  4746.   DPOKE GINTIN+4,init_w%
  4747.   DPOKE GINTIN+6,init_h%
  4748.   DPOKE GINTIN+8,fin_x%
  4749.   DPOKE GINTIN+10,fin_y%
  4750.   DPOKE GINTIN+12,fin_w%
  4751.   DPOKE GINTIN+14,fin_h%
  4752.   GEMSYS 73
  4753.   '
  4754. RETURN
  4755. '
  4756. PROCEDURE shrinkbox(fin_x%,fin_y%,fin_w%,fin_h%,init_x%,init_y%,init_w%,init_h%)
  4757.   '
  4758.   DPOKE GINTIN,fin_x%
  4759.   DPOKE GINTIN+2,fin_y%
  4760.   DPOKE GINTIN+4,fin_w%
  4761.   DPOKE GINTIN+6,fin_h%
  4762.   DPOKE GINTIN+8,init_x%
  4763.   DPOKE GINTIN+10,init_y%
  4764.   DPOKE GINTIN+12,init_w%
  4765.   DPOKE GINTIN+14,init_h%
  4766.   GEMSYS 74
  4767.   '
  4768. RETURN
  4769. '
  4770. PROCEDURE create_box(prompt$,value$,x0,y0,x1,y1)
  4771.   '
  4772.   TEXT 1,((y0+y1)/2)+3,prompt$
  4773.   TEXT x0+20,y0+20,value$
  4774.   BOX x0,y0,x1,y1
  4775.   '
  4776. RETURN
  4777. '
  4778. PROCEDURE redraw_box(value$,x0,y0,x1,y1)
  4779.   '
  4780.   DEFFILL 0,2,8
  4781.   PBOX x0+1,y0+1,x1-1,y1-1
  4782.   SHOWM
  4783.   TEXT x0+20,y0+20,value$
  4784.   '
  4785. RETURN
  4786.