home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / assemblr / library / sound / midi / macros.asm < prev    next >
Assembly Source File  |  1988-03-20  |  18KB  |  424 lines

  1. ;==============================================================
  2. ; include file, with MACROS for Modules
  3. ;--------------------------------------------------------------
  4. ; generate a random number in CX
  5. random  macro
  6.         local   randz
  7.         mov     cx,rseed        ;; get next raw seed
  8.         test    rhold,-1        ;; test for hold
  9.         jnz     randz           ;; do rand if not hold
  10.         add     cx,9248H        ;;     /
  11.         ror     cx,1            ;;    /
  12.         ror     cx,1            ;;   /
  13.         ror     cx,1            ;;  /
  14. randz:  mov     rseed,cx        ;; /
  15.         endm
  16. ;--------------------------------------------------------------
  17. ; generate a random number in DX
  18. randdx  macro
  19.         local   randz
  20.         mov     dx,rseed        ;; get next raw seed
  21.         test    rhold,-1        ;; test for hold
  22.         jnz     randz           ;; do rand if not hold
  23.         add     dx,9248H        ;;     /
  24.         ror     dx,1            ;;    /
  25.         ror     dx,1            ;;   /
  26.         ror     dx,1            ;;  /
  27. randz:  mov     rseed,dx        ;; /
  28.         endm
  29. ;--------------------------------------------------------------
  30. ; move value in first register to range specified by 2nd register
  31. ; locks up if 2nd register (max) = 0
  32. ;
  33. range   macro   reg,max 
  34.         local   rang0,rangx             ;; labels
  35. rang0:  cmp     reg,max                 ;; within range?
  36.         jb      rangx                   ;; yes, exit
  37.         sub     reg,max                 ;; no, foldover
  38.         jmp     short rang0             ;; check again
  39. rangx:  ;;
  40.         endm
  41. ;--------------------------------------------------------------
  42. ; normalize value in al to range 0 - 11 (octave)
  43. ; trashes dl, al; results in ah
  44. ;
  45. normal  macro   reg
  46.         local   normx
  47.         mov     ah,0                    ;; load for 0
  48.         or      al,al                   ;; zero not allowed
  49.         jz      normx                   ;; don't mod if 0
  50.         mov     dl,12                   ;; for octave
  51.         div     dl                      ;; mod 12
  52. normx:  ;;
  53.         endm
  54. ;--------------------------------------------------------------
  55. ; sort byte values in al, ah, dl, dh, in acending order
  56. ;
  57. sort4   macro
  58.         local   sorta,sortb,sortc,sortd,sorte,sortf
  59.         cmp     al,ah           ;; sort al,ah,dl,dh
  60.         jbe     sorta           ;; \
  61.         xchg    al,ah           ;;  \
  62. sorta:  cmp     al,dl           ;;   \
  63.         jbe     sortb           ;;    \
  64.         xchg    al,dl           ;;     \
  65. sortb:  cmp     al,dh           ;;      \  
  66.         jbe     sortc           ;;       \ 
  67.         xchg    al,dh           ;;        \
  68. sortc:  cmp     ah,dl           ;;         >
  69.         jbe     sortd           ;;        /
  70.         xchg    ah,dl           ;;       /
  71. sortd:  cmp     ah,dh           ;;      /
  72.         jbe     sorte           ;;     /
  73.         xchg    ah,dh           ;;    /
  74. sorte:  cmp     dl,dh           ;;   /
  75.         jbe     sortf           ;;  /
  76.         xchg    dl,dh           ;; /
  77. sortf:  ;;
  78.         endm
  79. ;--------------------------------------------------------------
  80. ; initialize a variable to a number
  81. ;
  82. initv   macro   vnum,inum
  83.         mov     vnum[di],offset word ptr dgroup:@zero+(inum*2)
  84.         endm
  85. ;--------------------------------------------------------------
  86. ; fetch a variable to a register
  87. ;
  88. getv    macro   reg,vnum
  89.         mov     bx,vnum[di]     ;; point to var addr
  90.         mov     reg,[bx]        ;; move the value to the register
  91.         endm
  92. ;--------------------------------------------------------------
  93. ; test variable against a byte
  94. ;
  95. testv   macro   vnum,tnum
  96.         mov     bx,vnum[di]     ;; point to var addr
  97.         test    byte ptr [bx],tnum 
  98.         endm
  99. ;--------------------------------------------------------------
  100. ; test for hold by nz in variable, or by master hold flag
  101. ; returns nz if hold
  102. ;
  103. hold    macro   vnum
  104.         mov     bx,vnum[di]     ;; point to var addr
  105.         mov     bl,[bx]         ;; get it
  106.         or      bl,mprstf       ;; check master reset
  107.         endm
  108. ;--------------------------------------------------------------
  109. ; store a register into the output byte
  110. ;
  111. putn    macro   reg
  112.         mov     outn[di],reg
  113.         endm
  114. ;--------------------------------------------------------------
  115. ; clock tick routine, exits cy set if tick, else cy clr
  116. ; uses bit 0 of hi byte of output as flag, other bits undistrubed
  117. ; call with 1st value the clock input, the 2nd value local storage
  118. ; identical to "TICK"
  119. ;-------------------------------------------------------------------
  120. tick    macro   varx,varz
  121.         local   tick1,tick2,tick3;; labels 
  122.         mov     bx,varx[di]     ;; get clock variable
  123.         test    byte ptr [bx],-1;; clock on or off
  124.         jz      tick1          ;; branch if it was off
  125.         test    byte ptr varz[di],1;; new one?
  126.         jnz     tick2          ;; no, exit clock off
  127.         or      byte ptr varz[di],1;; yes, set Last
  128.         stc                    ;; clock on
  129.         jmp     short tick3    ;; branch
  130. tick1:  and     byte ptr varz[di],0FEH;; clk off, clear Last
  131. tick2:  clc                     ;; clock off 
  132. tick3   =       $
  133.         endm
  134. ;--------------------------------------------------------------
  135. ; clock tick routine, exits cy set if tick, else cy clr
  136. ; uses bit 1 of hi byte of output as flag, other bits undistrubed
  137. ; call with 1st value the clock input, the 2nd value local storage
  138. ; identical to "TICK", except bit 1 of 2nd variable is flag
  139. ;-------------------------------------------------------------------
  140. tickb1  macro   varx,varz
  141.         local   tick1,tick2,tick3;; labels 
  142.         mov     bx,varx[di]     ;; get clock variable
  143.         test    byte ptr [bx],-1;; clock on or off
  144.         jz      tick1          ;; branch if it was off
  145.         test    byte ptr varz[di],2;; new one?
  146.         jnz     tick2          ;; no, exit clock off
  147.         or      byte ptr varz[di],2;; yes, set Last
  148.         stc                    ;; clock on
  149.         jmp     short tick3    ;; branch
  150. tick1:  and     byte ptr varz[di],0FDH;; clk off, clear Last
  151. tick2:  clc                     ;; clock off 
  152. tick3   =       $
  153.         endm
  154. ;--------------------------------------------------------------
  155. ; clock tick routine, exits cy set if tick, else cy clr
  156. ; uses bit 2 of hi byte of output as flag, other bits undistrubed
  157. ; call with 1st value the clock input, the 2nd value local storage
  158. ; identical to "TICK", except bit 2 of 2nd variable is flag
  159. ;-------------------------------------------------------------------
  160. tickb2  macro   varx,varz
  161.         local   tick1,tick2,tick3;; labels 
  162.         mov     bx,varx[di]     ;; get clock variable
  163.         test    byte ptr [bx],-1;; clock on or off
  164.         jz      tick1          ;; branch if it was off
  165.         test    byte ptr varz[di],4;; new one?
  166.         jnz     tick2          ;; no, exit clock off
  167.         or      byte ptr varz[di],4;; yes, set Last
  168.         stc                    ;; clock on
  169.         jmp     short tick3    ;; branch
  170. tick1:  and     byte ptr varz[di],0FBH;; clk off, clear Last
  171. tick2:  clc                     ;; clock off 
  172. tick3   =       $
  173.         endm
  174. ;--------------------------------------------------------------
  175. ; clock tick routine, exits cy set if tick, else cy clr
  176. ; uses bit 3 of hi byte of output as flag, other bits undistrubed
  177. ; call with 1st value the clock input, the 2nd value local storage
  178. ; identical to "TICK", except bit 3 of 2nd variable is flag
  179. ;-------------------------------------------------------------------
  180. tickb3  macro   varx,varz
  181.         local   tick1,tick2,tick3;; labels 
  182.         mov     bx,varx[di]     ;; get clock variable
  183.         test    byte ptr [bx],-1;; clock on or off
  184.         jz      tick1          ;; branch if it was off
  185.         test    byte ptr varz[di],8;; new one?
  186.         jnz     tick2          ;; no, exit clock off
  187.         or      byte ptr varz[di],8;; yes, set Last
  188.         stc                    ;; clock on
  189.         jmp     short tick3    ;; branch
  190. tick1:  and     byte ptr varz[di],0F7H;; clk off, clear Last
  191. tick2:  clc                     ;; clock off 
  192. tick3   =       $
  193.         endm
  194. ;--------------------------------------------------------------
  195. ; clock tick routine, exits cy set if tick, else cy clr
  196. ; uses bit 3 of hi byte of output as flag, other bits undistrubed
  197. ; call with 1st value the clock input, the 2nd value local storage
  198. ; identical to "TICK", except bit 3 of 2nd variable is flag
  199. ;-------------------------------------------------------------------
  200. tickb4  macro   varx,varz
  201.         local   tick1,tick2,tick3;; labels 
  202.         mov     bx,varx[di]     ;; get clock variable
  203.         test    byte ptr [bx],-1;; clock on or off
  204.         jz      tick1          ;; branch if it was off
  205.         test    byte ptr varz[di],10h;; new one?
  206.         jnz     tick2          ;; no, exit clock off
  207.         or      byte ptr varz[di],10h;; yes, set Last
  208.         stc                    ;; clock on
  209.         jmp     short tick3    ;; branch
  210. tick1:  and     byte ptr varz[di],0EFH;; clk off, clear Last
  211. tick2:  clc                     ;; clock off 
  212. tick3   =       $
  213.         endm
  214. ;--------------------------------------------------------------
  215. ; set es:bx to screen tag address
  216. ;
  217. gettag  macro
  218.         mov     es,4[di]        ;; get seg addr
  219.         mov     bx,6[di]        ;; get module screen address
  220.         endm
  221. ;--------------------------------------------------------------
  222. ; convert binary in al to hex in ax
  223. ;
  224. tohex   macro
  225.         rol     al,1
  226.         rol     al,1
  227.         rol     al,1
  228.         rol     al,1
  229.         mov     ah,al
  230.         and     al,0FH
  231.         daa
  232.         add     al,0F0H
  233.         adc     al,040H
  234.         ;
  235.         xchg    al,ah
  236.         rol     al,1
  237.         rol     al,1
  238.         rol     al,1
  239.         rol     al,1
  240.         and     al,00FH
  241.         daa
  242.         add     al,0F0H
  243.         adc     al,040H
  244.         endm
  245. ;--------------------------------------------------------------
  246. ; get next byte from pass buffer and send to midi
  247. ; does nothing if midi output port is busy  
  248. ; or if the buffer is empty
  249. sendmb  macro
  250.         call    sendm
  251.         endm
  252. ;--------------------------------------------------------------
  253. ; set channel flag, strip ms channel information
  254. ;
  255. mchan   macro   reg
  256.         mov     midip,reg
  257.         and     reg,0FH
  258.         endm
  259. ;--------------------------------------------------------------
  260. ; The normal exit routine for all modules.
  261. ; if the hi byte of the output variable is different from the 
  262. ; low byte, the low byte is displayed on the screen, and put
  263. ; into the hi byte.  Then the MIDI output routine is invoked,
  264. ; The module execution pointer (SI) is bumped, the variable
  265. ; list pointer (DI) for the next module is set up, and control
  266. ; is passed to next module on the execution list.
  267. ;
  268. nextv   macro
  269.         jmp     _nextv          ;; jump, rather copy the code
  270.         endm
  271. ;--------------------------------------------------------------
  272. @nextv  macro
  273.         local   next1           ;; label
  274.         mov     al,outn[di]     ;; get low byte of output
  275.         cmp     al,outn+1[di]   ;; same as before ?
  276.         jz      next1           ;; yes, branch
  277.         mov     outn+1[di],al   ;; no, set up "done"
  278.         mov     es,4[di]        ;; get seg addr
  279.         mov     bx,6[di]        ;; get module screen address
  280.         tohex                   ;; convert to hex word
  281.         mov     es:320[bx],ah   ;; put to the screen
  282.         mov     es:322[bx],al   ;; /
  283. next1:  sendmb                  ;; send next midi buffer byte
  284.         add     si,4            ;; point to next module exe addr
  285.         mov     di,2[si]        ;; set di pointing to variable list
  286.         jmp     [si]            ;; go for it
  287.         endm
  288. ;--------------------------------------------------------------
  289. ; The "easy exit" routine for modules.
  290. ; No screen update. The MIDI output routine is invoked,
  291. ; The module execution pointer (SI) is bumped, the variable
  292. ; list pointer (DI) for the next module is set up, and control
  293. ; is passed to next module on the execution list.
  294. ;
  295. nextx   macro
  296.         jmp     _nextx          ;; jump, rather copy the code
  297.         endm
  298. ;--------------------------------------------------------------
  299. @nextx  macro
  300.         sendmb                  ;; send next midi buffer byte
  301.         add     si,4            ;; point to next module exe addr
  302.         mov     di,2[si]        ;; set di pointing to variable list
  303.         jmp     [si]            ;; go for it
  304.         endm
  305. ;--------------------------------------------------------------
  306. ; This is the same as NEXTV, but it also sets the red led
  307. ; If the hi byte of the output variable is different from the 
  308. ; low byte, the low byte is displayed on the screen, and put
  309. ; into the hi byte. Next, the low byte is tested; if NZ, the
  310. ; LED is turned on, else it is turned on.
  311. ; Then the MIDI output routine is invoked.
  312. ; The module execution pointer (SI) is bumped, the variable
  313. ; list pointer (DI) for the next module is set up, and control
  314. ; is passed to next module on the execution list.
  315. ;
  316. nextl   macro
  317.         jmp     _nextl          ;; jump, rather copy the code
  318.         endm
  319. ;--------------------------------------------------------------
  320. @nextl  macro
  321.         local   next1,next2     ;; labels
  322.         mov     al,outn[di]     ;; get low byte of output
  323.         cmp     al,outn+1[di]   ;; same as before ?
  324.         jz      next1           ;; yes, branch
  325.         mov     outn+1[di],al   ;; no, set up "done"
  326.         mov     es,4[di]        ;; get seg addr
  327.         mov     bx,6[di]        ;; get module screen address
  328.         mov     dl,al           ;; save in dl
  329.         tohex                   ;; convert to hex word
  330.         mov     es:320[bx],ah   ;; put to the screen
  331.         mov     es:322[bx],al   ;; /
  332.         dec     bx              ;; point to led
  333.         or      dl,dl           ;; test for z
  334.         mov     al,red          ;; set up for z
  335.         jz      next2           ;; branch if z
  336.         mov     al,red+hi       ;; else set up for nz
  337. next2:  mov     es:[bx],al      ;; set the led
  338. next1:  sendmb                  ;; send next midi buffer byte
  339.         add     si,4            ;; point to next module exe addr
  340.         mov     di,2[si]        ;; set di pointing to variable list
  341.         jmp     [si]            ;; go for it
  342.         endm
  343. ;--------------------------------------------------------------
  344. ; This NEXT is used when the output is to be a one-shot, only
  345. ; set hi for one cycle.
  346. ; If the output is low when the routine is called, it does nothing.
  347. ; If the output is hi, it displays & sends to MIDI, upon the next
  348. ; cycle, the output will be set to low.
  349. ;
  350. nextt   macro
  351.         jmp     _nextt          ;; jump, rather copy the code
  352.         endm
  353. ;--------------------------------------------------------------
  354. @nextt  macro
  355.         local   next1,next2,next3 ;; labels
  356.         mov     ax,outn[di]     ;; get hi & low byte of output
  357.         or      al,ah           ;; anything there 
  358.         jz      next1           ;; no, easy exit
  359.         ;;
  360.         test    ah,-1           ;; 2nd time around?
  361.         mov     ah,al           ;; (set up)
  362.         jz      next3           ;; no, branch
  363.         mov     ax,0            ;; yes, zip it
  364.         ;;
  365. next3:  mov     outn[di],ax     ;; /
  366.         mov     es,4[di]        ;; get seg addr
  367.         mov     bx,6[di]        ;; get module screen address
  368.         mov     dl,al           ;; save in dl
  369.         tohex                   ;; convert to hex word
  370.         mov     es:320[bx],ah   ;; put to the screen
  371.         mov     es:322[bx],al   ;; /
  372.         dec     bx              ;; point to led
  373.         or      dl,dl           ;; test for z
  374.         mov     al,red          ;; set up for z
  375.         jz      next2           ;; branch if z
  376.         mov     al,red+hi       ;; else set up for nz
  377. next2:  mov     es:[bx],al      ;; set the led
  378. next1:  sendmb                  ;; send next midi buffer byte
  379.         add     si,4            ;; point to next module exe addr
  380.         mov     di,2[si]        ;; set di pointing to variable list
  381.         jmp     [si]            ;; go for it
  382.         endm
  383. ;--------------------------------------------------------------
  384. ; macro to display a magenta input value
  385. ; displays ls byte at value location
  386. ; assumes si = 6[di], es = 4[di]
  387. ;
  388. showpv  macro   value
  389.         mov     al,((value*2)+var0)[di]    ;; get the binary value
  390.         tohex                              ;; convert to hex in ax
  391.         mov     es:((value*160)+480)[si],ah;; put it to the screen
  392.         mov     es:((value*160)+482)[si],al;; put it to the screen
  393.         endm
  394. ;--------------------------------------------------------------
  395. ; macro to display a magenta input value
  396. ; displays ms byte at value location + 1
  397. ; assumes si = 6[di], es = 4[di]
  398. ;
  399. showpp  macro   value
  400.         mov     al,((value*2)+var0+1)[di]  ;; get the binary value
  401.         tohex                              ;; convert to hex in ax
  402.         mov     es:((value*160)+480)[si],ah;; put it to the screen
  403.         mov     es:((value*160)+482)[si],al;; put it to the screen
  404.         endm
  405. ;--------------------------------------------------------------
  406. ; macro to display a magenta input value, only if value <> value+1
  407. ; displays ls byte at value location, sets value = value+1
  408. ; assumes si = 6[di], es = 4[di]
  409. ;
  410. showpq  macro   value
  411.         local   boogie                     ;; label for exit
  412.         mov     al,((value*2)+var0)[di]    ;; get the binary value
  413.         cmp     al,((value*2)+var0+1)[di]  ;; changed?
  414.         jz      boogie                     ;; no, split
  415.         mov     ((value*2)+var0+1)[di],al  ;; set value+1 <-- value
  416.         tohex                              ;; convert to hex in ax
  417.         mov     es:((value*160)+480)[si],ah;; put it to the screen
  418.         mov     es:((value*160)+482)[si],al;; put it to the screen
  419. boogie  = $
  420.         endm
  421.