home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / sound / midi / midilb20.lha / czplus < prev    next >
Text File  |  1988-05-05  |  7KB  |  285 lines

  1. 'CZPLUS for the Amiga by Jim McConkey
  2. ' loosely adapted from the C64 version by Tim Dowty
  3. '  published in Electronic Musician Feb. & Aug. 1987
  4.  
  5. CLS : LOCATE 1,1
  6.  
  7. DEFLNG a-Z
  8. RANDOMIZE TIMER
  9. DEF FNrnd16=INT(RND*16)
  10. Casio%=&H44 : MMF.SYSEX=&H400
  11.  
  12. 'Assumes a subdirectory defined by Path$ off the current directory
  13. ' for the storage of patch files
  14. Path$="CZfiles"
  15.  
  16. 'Assumes exec.bmap and midi.bmap in the current directory
  17. LIBRARY "exec.library"
  18. LIBRARY "midi.library"
  19.  
  20. Declarations:
  21.  DECLARE FUNCTION AllocMem() LIBRARY
  22.  memf.public = 1
  23.  memf.clear = 65536&
  24.  
  25.  DECLARE FUNCTION CreateMDest() LIBRARY
  26.  DECLARE FUNCTION CreateMSource() LIBRARY
  27.  DECLARE FUNCTION GetMidiMsg() LIBRARY
  28.  DECLARE FUNCTION MidiMsgLength() LIBRARY
  29.  DECLARE FUNCTION MRouteDest() LIBRARY
  30.  DECLARE FUNCTION MRouteSource() LIBRARY
  31.  DestName$="MidiOut"+CHR$(0)
  32.  SourceName$="MidiIn"+CHR$(0)
  33.  
  34. 'sysex voice request and header:
  35.  RequestSize=10 : HeaderSize=8
  36.  DIM SHARED Rqst(RequestSize-1),Header(HeaderSize-1)
  37.  DATA &hF0,&h44,0,0,&h70,&h10,0,&h70,&h31,&hF7
  38.  DATA &hF0,&h44,0,0,&h70,&h20,0,&hF7
  39.  
  40. AllocateBuffers:
  41.  VoiceSize=264 : MainSize=16*VoiceSize
  42.  RandomSize=VoiceSize
  43.  main=AllocMem(MainSize,memf.public+memf.clear)
  44.  IF main=0 THEN CloseDown
  45.  Random=AllocMem(RandomSize,memf.public+memf.clear)
  46.  IF Random=0 THEN CloseDown
  47.  Request=AllocMem(RequestSize,memf.public+memf.clear)
  48.  IF Request=0 THEN CloseDown
  49.  
  50. SetupMIDIRoute:
  51.  RouteInfoSize=14
  52.  RouteInfo=AllocMem(RouteInfoSize,memf.public+memf.clear)
  53.  IF RouteInfo=0 THEN CloseDown
  54. ' POKEW RouteInfo  ,MMF.SYSEX  'Allow only Casio Sysex messages
  55. ' POKE  RouteInfo+8,1          'on Channel 1
  56. ' POKE  RouteInfo+9,Casio%
  57.  POKEW RouteInfo  ,MMF.SYSEX   'Allow only Sysex messages
  58.  POKE  RouteInfo+6,1           'for just one manufacturer
  59.  POKE  RouteInfo+7,Casio%      'which is in this case Casio
  60.  
  61. CZPLUS:
  62.  
  63.  PRINT"CZPLUS for the Amiga"
  64.  PRINT" by Jim McConkey after C64 original by Tim Dowty"
  65.  GOSUB Init
  66.  Dest=CreateMDest(0&,0&)
  67.  IF Dest=0 THEN PRINT"Can't create Dest": GOTO CloseDown
  68.  Source=CreateMSource(0&,0&)
  69.  IF Source=0 THEN PRINT"Can't create Source": GOTO CloseDown
  70.  
  71.  Out=MRouteSource(Source,SADD(DestName$),RouteInfo)
  72.  IF Out=0 THEN PRINT"Can't route MIDI output": GOTO CloseDown
  73.  In=MRouteDest(SADD(SourceName$),Dest,RouteInfo)
  74.  IF In=0 THEN PRINT"Can't route MIDI input" : GOTO CloseDown
  75.  
  76.  MENU 1,0,1,"CZPLUS"
  77.  MENU 1,1,1,"Quit        "
  78.  
  79.  MENU 2,0,1,"MIDI"
  80.  MENU 2,1,1,"Random Patch     "
  81.  MENU 2,2,1,"Get Presets      "
  82.  MENU 2,3,1,"Get Internals    "
  83.  MENU 2,4,1,"Get Cartridge    "
  84.  MENU 2,5,1,"Send to Internals"
  85.  
  86.  MENU 3,0,1,"FILES"
  87.  MENU 3,1,1,"Load File"
  88.  MENU 3,2,1,"Save File"
  89.  MENU 3,3,1,"Directory"
  90.  
  91.  MENU 4,0,0,""
  92.  ON MENU GOSUB MenuHandler
  93.  MENU ON
  94.  
  95.  Quit%=0
  96.  WHILE NOT Quit%
  97.   SLEEP
  98.  WEND
  99.  CLS : MENU RESET
  100.  
  101. CloseDown:
  102.  IF Dest<>0 THEN CALL DeleteMDest(Dest)
  103.  IF Source<>0 THEN CALL DeleteMSource(Source)
  104.  IF In<>0 THEN CALL DeleteMRoute(In)
  105.  IF Out<>0 THEN CALL DeleteMRoute(Out)
  106.  IF RouteInfo<>0 THEN CALL FreeMem(RouteInfo,RouteInfoSize)
  107.  IF main<>0 THEN CALL FreeMem(main,MainSize)
  108.  IF Request<>0 THEN CALL FreeMem(Request,RequestSize)
  109.  IF Random<>0 THEN CALL FreeMem(Random,RandomSize)
  110.  LIBRARY CLOSE
  111. END
  112.  
  113. MenuHandler:
  114.  MenuID%=MENU(0) : MenuItem%=MENU(1)
  115.  IF MenuID%=1 THEN
  116.   ON MenuItem% GOSUB Quit
  117.  ELSEIF MenuID%=2 THEN
  118.   ON MenuItem% GOSUB RandomPatch,GetPre,GetInt,GetCart,Send
  119.  ELSEIF MenuID%=3 THEN
  120.   ON MenuItem% GOSUB LoadFile,SaveFile,Directory
  121.  END IF
  122. RETURN
  123.  
  124. RandomPatch:
  125.  LOCATE 5,1 : PRINT"Generating Patch ...       "
  126.  addr=Random : POKE addr+6,&H60
  127.  FOR i=7 TO 262
  128.   POKE addr+i,PEEK(main+i+VoiceSize*FNrnd16)
  129.  NEXT
  130.  LOCATE 5,1 : PRINT "Sending Patch ...         "
  131.  CALL PutMidiMsg(Source,addr) : RcvdPtr=0
  132.  FOR i=200 TO 0 STEP -1
  133.   RcvdPtr=GetMidiMsg(Dest)
  134.   IF RcvdPtr<>0 THEN i=-1
  135.  NEXT
  136.  IF RcvdPtr<>0 THEN CALL FreeMidiMsg(RcvdPtr)
  137.  LOCATE 5,1 : PRINT SPACE$(30)
  138. RETURN
  139.  
  140. Quit:
  141.  Quit%=-1
  142. RETURN
  143.  
  144. GetPre:
  145.  LOCATE 6,1 : PRINT SPACE$(30)
  146.  FOR voice=&H0 TO &HF
  147.   CALL GetVoice(voice,oops)
  148.   IF oops THEN voice=&HFF
  149.  NEXT
  150.  IF voice<>&H100 THEN LOCATE 5,1 : PRINT "Presets received!     "
  151. RETURN
  152.  
  153. GetInt:
  154.  LOCATE 6,1 : PRINT SPACE$(30)
  155.  FOR voice=&H20 TO &H2F
  156.   CALL GetVoice(voice,oops)
  157.   IF oops THEN voice=&HFF
  158.  NEXT
  159.  IF voice<>&H100 THEN LOCATE 5,1 : PRINT "Internals received!     "
  160. RETURN
  161.  
  162. GetCart:
  163.  LOCATE 6,1 : PRINT SPACE$(30)
  164.  FOR voice=&H40 TO &H4F
  165.   CALL GetVoice(voice,oops)
  166.   IF oops THEN voice=&HFF
  167.  NEXT
  168.  IF voice<>&H100 THEN LOCATE 5,1 : PRINT "Cartridge received!     "
  169. RETURN
  170.  
  171. Send:
  172.  addr=main
  173.  FOR voice=32 TO 47
  174.   LOCATE 5,1 : PRINT "Sending voice"voice+1"     "
  175.   POKE addr+6,voice
  176.   CALL PutMidiMsg(Source,addr)
  177.   FOR i=200 TO 0 STEP -1
  178.    RcvdPtr=GetMidiMsg(Dest)
  179.    IF RcvdPtr<>0 THEN i=-1
  180.   NEXT
  181.   IF RcvdPtr<>0 THEN CALL FreeMidiMsg(RcvdPtr)
  182.   addr=addr+VoiceSize
  183.  NEXT voice
  184.  LOCATE 5,1 : PRINT "Finished sending bank.  "
  185. RETURN
  186.  
  187. LoadFile:
  188.  ON ERROR GOTO LoadErrMsg
  189.  LOCATE 5,1 : INPUT "File to get patches from: ",FileName$
  190.  LOCATE 5,1 : PRINT "Reading patches from "FileName$" ..."SPACE$(15)
  191.  OPEN Path$+"/"+FileName$ FOR INPUT AS 1
  192.  FOR i=0 TO MainSize-1
  193.   POKE main+i,ASC(INPUT$(1,1))
  194.  NEXT
  195.  LOCATE 5,1 : PRINT SPACE$(50)
  196. EndLoad:
  197.  CLOSE #1
  198. RETURN
  199.  
  200. SaveFile:
  201.  ON ERROR GOTO SaveErrMsg
  202.  LOCATE 5,1 : INPUT "File to save patches to: ",FileName$
  203.  LOCATE 5,1 : PRINT "Saving patches to "FileName$" ..."SPACE$(15)
  204.  OPEN Path$+"/"+FileName$ FOR OUTPUT AS 1
  205.  FOR i=main TO main+MainSize-1
  206.   PRINT#1,CHR$(PEEK(i));
  207.  NEXT
  208.  LOCATE 5,1 : PRINT SPACE$(50)
  209. EndSave:
  210.  CLOSE #1
  211. RETURN
  212.  
  213. LoadErrMsg:
  214.  LOCATE 5,1
  215.  IF ERR=53 THEN
  216.   PRINT "File not found" SPACE$(30)
  217.  ELSEIF ERR=70 THEN
  218.   PRINT "Disk is write protected" SPACE$(20)
  219.  ELSE
  220.   PRINT "Load error" SPACE$(30)
  221.  END IF
  222. RESUME EndLoad
  223.  
  224. SaveErrMsg:
  225.  LOCATE 5,1
  226.  IF ERR=70 THEN
  227.   PRINT "Disk is write protected"
  228.  ELSE
  229.   PRINT "Write error"
  230.  END IF
  231. RESUME EndSave
  232.  
  233. Directory:
  234.  CLS : FILES Path$ : MENU OFF
  235.  PRINT : PRINT"Touch any key to continue"
  236.  WHILE INKEY$="" : WEND : MENU ON
  237.  CLS : PRINT"CZPLUS for the Amiga"
  238.  PRINT" by Jim McConkey after C64 original by Tim Dowty"
  239. RETURN
  240.  
  241. Init:
  242. 'Set up voice request message
  243.  FOR i=0 TO RequestSize-1
  244.   READ Rqst(i) : POKE Request+i,Rqst(i)
  245.  NEXT
  246. 'Put sysex headers in buffers
  247.  FOR i=0 TO HeaderSize-1: READ Header(i) : NEXT
  248.  FOR voice=0 TO 15
  249.   addr=main+voice*VoiceSize
  250.   FOR i=0 TO 7
  251.    POKE addr+i,Header(i)
  252.   NEXT i
  253.   i=VoiceSize-1 : POKE addr+i,Header(7)
  254.  NEXT voice
  255.   addr=Random
  256.   FOR i=0 TO 7
  257.    POKE addr+i,Header(i)
  258.   NEXT i
  259.   i=VoiceSize-1 : POKE addr+i,Header(7)
  260. RETURN
  261.  
  262. SUB GetVoice(voice,oops) STATIC
  263.  SHARED main,Request,VoiceSize,Source,Dest
  264.  LOCATE 5,1 : PRINT "Getting voice"voice+1"       "
  265.  POKE Request+6,voice : CALL PutMidiMsg(Source,Request)
  266.  FOR i=200 TO 0 STEP -1
  267.   RcvdPtr=GetMidiMsg(Dest)
  268.   IF RcvdPtr<>0 THEN i=-1
  269.  NEXT
  270.  IF RcvdPtr=0 THEN
  271.   LOCATE 5,1 : PRINT "CZ is not responding!     " : oops=-1
  272.  ELSE
  273.   addr=main+VoiceSize*(voice AND 15)+7
  274.   RcvdPtr=RcvdPtr+6
  275.   FOR i=0 TO 255
  276.    POKE addr+i,PEEK(RcvdPtr+i)
  277.   NEXT
  278.   FreeMidiMsg(RcvdPtr-6) : oops=0
  279.  END IF
  280. END SUB
  281.  
  282.  
  283.  
  284.  
  285.