home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Audio Version 4.94
/
audioversion4.94knowledgemediaresourcelibraryoctober1994.iso
/
msdos
/
musicbox
/
macros.asm
< prev
next >
Wrap
Assembly Source File
|
1988-03-20
|
18KB
|
424 lines
;==============================================================
; include file, with MACROS for Modules
;--------------------------------------------------------------
; generate a random number in CX
;
random macro
local randz
mov cx,rseed ;; get next raw seed
test rhold,-1 ;; test for hold
jnz randz ;; do rand if not hold
add cx,9248H ;; /
ror cx,1 ;; /
ror cx,1 ;; /
ror cx,1 ;; /
randz: mov rseed,cx ;; /
endm
;--------------------------------------------------------------
; generate a random number in DX
;
randdx macro
local randz
mov dx,rseed ;; get next raw seed
test rhold,-1 ;; test for hold
jnz randz ;; do rand if not hold
add dx,9248H ;; /
ror dx,1 ;; /
ror dx,1 ;; /
ror dx,1 ;; /
randz: mov rseed,dx ;; /
endm
;--------------------------------------------------------------
; move value in first register to range specified by 2nd register
; locks up if 2nd register (max) = 0
;
range macro reg,max
local rang0,rangx ;; labels
rang0: cmp reg,max ;; within range?
jb rangx ;; yes, exit
sub reg,max ;; no, foldover
jmp short rang0 ;; check again
rangx: ;;
endm
;--------------------------------------------------------------
; normalize value in al to range 0 - 11 (octave)
; trashes dl, al; results in ah
;
normal macro reg
local normx
mov ah,0 ;; load for 0
or al,al ;; zero not allowed
jz normx ;; don't mod if 0
mov dl,12 ;; for octave
div dl ;; mod 12
normx: ;;
endm
;--------------------------------------------------------------
; sort byte values in al, ah, dl, dh, in acending order
;
sort4 macro
local sorta,sortb,sortc,sortd,sorte,sortf
cmp al,ah ;; sort al,ah,dl,dh
jbe sorta ;; \
xchg al,ah ;; \
sorta: cmp al,dl ;; \
jbe sortb ;; \
xchg al,dl ;; \
sortb: cmp al,dh ;; \
jbe sortc ;; \
xchg al,dh ;; \
sortc: cmp ah,dl ;; >
jbe sortd ;; /
xchg ah,dl ;; /
sortd: cmp ah,dh ;; /
jbe sorte ;; /
xchg ah,dh ;; /
sorte: cmp dl,dh ;; /
jbe sortf ;; /
xchg dl,dh ;; /
sortf: ;;
endm
;--------------------------------------------------------------
; initialize a variable to a number
;
initv macro vnum,inum
mov vnum[di],offset word ptr dgroup:@zero+(inum*2)
endm
;--------------------------------------------------------------
; fetch a variable to a register
;
getv macro reg,vnum
mov bx,vnum[di] ;; point to var addr
mov reg,[bx] ;; move the value to the register
endm
;--------------------------------------------------------------
; test variable against a byte
;
testv macro vnum,tnum
mov bx,vnum[di] ;; point to var addr
test byte ptr [bx],tnum
endm
;--------------------------------------------------------------
; test for hold by nz in variable, or by master hold flag
; returns nz if hold
;
hold macro vnum
mov bx,vnum[di] ;; point to var addr
mov bl,[bx] ;; get it
or bl,mprstf ;; check master reset
endm
;--------------------------------------------------------------
; store a register into the output byte
;
putn macro reg
mov outn[di],reg
endm
;--------------------------------------------------------------
; clock tick routine, exits cy set if tick, else cy clr
; uses bit 0 of hi byte of output as flag, other bits undistrubed
; call with 1st value the clock input, the 2nd value local storage
; identical to "TICK"
;-------------------------------------------------------------------
tick macro varx,varz
local tick1,tick2,tick3;; labels
mov bx,varx[di] ;; get clock variable
test byte ptr [bx],-1;; clock on or off
jz tick1 ;; branch if it was off
test byte ptr varz[di],1;; new one?
jnz tick2 ;; no, exit clock off
or byte ptr varz[di],1;; yes, set Last
stc ;; clock on
jmp short tick3 ;; branch
tick1: and byte ptr varz[di],0FEH;; clk off, clear Last
tick2: clc ;; clock off
tick3 = $
endm
;--------------------------------------------------------------
; clock tick routine, exits cy set if tick, else cy clr
; uses bit 1 of hi byte of output as flag, other bits undistrubed
; call with 1st value the clock input, the 2nd value local storage
; identical to "TICK", except bit 1 of 2nd variable is flag
;-------------------------------------------------------------------
tickb1 macro varx,varz
local tick1,tick2,tick3;; labels
mov bx,varx[di] ;; get clock variable
test byte ptr [bx],-1;; clock on or off
jz tick1 ;; branch if it was off
test byte ptr varz[di],2;; new one?
jnz tick2 ;; no, exit clock off
or byte ptr varz[di],2;; yes, set Last
stc ;; clock on
jmp short tick3 ;; branch
tick1: and byte ptr varz[di],0FDH;; clk off, clear Last
tick2: clc ;; clock off
tick3 = $
endm
;--------------------------------------------------------------
; clock tick routine, exits cy set if tick, else cy clr
; uses bit 2 of hi byte of output as flag, other bits undistrubed
; call with 1st value the clock input, the 2nd value local storage
; identical to "TICK", except bit 2 of 2nd variable is flag
;-------------------------------------------------------------------
tickb2 macro varx,varz
local tick1,tick2,tick3;; labels
mov bx,varx[di] ;; get clock variable
test byte ptr [bx],-1;; clock on or off
jz tick1 ;; branch if it was off
test byte ptr varz[di],4;; new one?
jnz tick2 ;; no, exit clock off
or byte ptr varz[di],4;; yes, set Last
stc ;; clock on
jmp short tick3 ;; branch
tick1: and byte ptr varz[di],0FBH;; clk off, clear Last
tick2: clc ;; clock off
tick3 = $
endm
;--------------------------------------------------------------
; clock tick routine, exits cy set if tick, else cy clr
; uses bit 3 of hi byte of output as flag, other bits undistrubed
; call with 1st value the clock input, the 2nd value local storage
; identical to "TICK", except bit 3 of 2nd variable is flag
;-------------------------------------------------------------------
tickb3 macro varx,varz
local tick1,tick2,tick3;; labels
mov bx,varx[di] ;; get clock variable
test byte ptr [bx],-1;; clock on or off
jz tick1 ;; branch if it was off
test byte ptr varz[di],8;; new one?
jnz tick2 ;; no, exit clock off
or byte ptr varz[di],8;; yes, set Last
stc ;; clock on
jmp short tick3 ;; branch
tick1: and byte ptr varz[di],0F7H;; clk off, clear Last
tick2: clc ;; clock off
tick3 = $
endm
;--------------------------------------------------------------
; clock tick routine, exits cy set if tick, else cy clr
; uses bit 3 of hi byte of output as flag, other bits undistrubed
; call with 1st value the clock input, the 2nd value local storage
; identical to "TICK", except bit 3 of 2nd variable is flag
;-------------------------------------------------------------------
tickb4 macro varx,varz
local tick1,tick2,tick3;; labels
mov bx,varx[di] ;; get clock variable
test byte ptr [bx],-1;; clock on or off
jz tick1 ;; branch if it was off
test byte ptr varz[di],10h;; new one?
jnz tick2 ;; no, exit clock off
or byte ptr varz[di],10h;; yes, set Last
stc ;; clock on
jmp short tick3 ;; branch
tick1: and byte ptr varz[di],0EFH;; clk off, clear Last
tick2: clc ;; clock off
tick3 = $
endm
;--------------------------------------------------------------
; set es:bx to screen tag address
;
gettag macro
mov es,4[di] ;; get seg addr
mov bx,6[di] ;; get module screen address
endm
;--------------------------------------------------------------
; convert binary in al to hex in ax
;
tohex macro
rol al,1
rol al,1
rol al,1
rol al,1
mov ah,al
and al,0FH
daa
add al,0F0H
adc al,040H
;
xchg al,ah
rol al,1
rol al,1
rol al,1
rol al,1
and al,00FH
daa
add al,0F0H
adc al,040H
endm
;--------------------------------------------------------------
; get next byte from pass buffer and send to midi
; does nothing if midi output port is busy
; or if the buffer is empty
;
sendmb macro
call sendm
endm
;--------------------------------------------------------------
; set channel flag, strip ms channel information
;
mchan macro reg
mov midip,reg
and reg,0FH
endm
;--------------------------------------------------------------
; The normal exit routine for all modules.
; if the hi byte of the output variable is different from the
; low byte, the low byte is displayed on the screen, and put
; into the hi byte. Then the MIDI output routine is invoked,
; The module execution pointer (SI) is bumped, the variable
; list pointer (DI) for the next module is set up, and control
; is passed to next module on the execution list.
;
nextv macro
jmp _nextv ;; jump, rather copy the code
endm
;--------------------------------------------------------------
@nextv macro
local next1 ;; label
mov al,outn[di] ;; get low byte of output
cmp al,outn+1[di] ;; same as before ?
jz next1 ;; yes, branch
mov outn+1[di],al ;; no, set up "done"
mov es,4[di] ;; get seg addr
mov bx,6[di] ;; get module screen address
tohex ;; convert to hex word
mov es:320[bx],ah ;; put to the screen
mov es:322[bx],al ;; /
next1: sendmb ;; send next midi buffer byte
add si,4 ;; point to next module exe addr
mov di,2[si] ;; set di pointing to variable list
jmp [si] ;; go for it
endm
;--------------------------------------------------------------
; The "easy exit" routine for modules.
; No screen update. The MIDI output routine is invoked,
; The module execution pointer (SI) is bumped, the variable
; list pointer (DI) for the next module is set up, and control
; is passed to next module on the execution list.
;
nextx macro
jmp _nextx ;; jump, rather copy the code
endm
;--------------------------------------------------------------
@nextx macro
sendmb ;; send next midi buffer byte
add si,4 ;; point to next module exe addr
mov di,2[si] ;; set di pointing to variable list
jmp [si] ;; go for it
endm
;--------------------------------------------------------------
; This is the same as NEXTV, but it also sets the red led
; If the hi byte of the output variable is different from the
; low byte, the low byte is displayed on the screen, and put
; into the hi byte. Next, the low byte is tested; if NZ, the
; LED is turned on, else it is turned on.
; Then the MIDI output routine is invoked.
; The module execution pointer (SI) is bumped, the variable
; list pointer (DI) for the next module is set up, and control
; is passed to next module on the execution list.
;
nextl macro
jmp _nextl ;; jump, rather copy the code
endm
;--------------------------------------------------------------
@nextl macro
local next1,next2 ;; labels
mov al,outn[di] ;; get low byte of output
cmp al,outn+1[di] ;; same as before ?
jz next1 ;; yes, branch
mov outn+1[di],al ;; no, set up "done"
mov es,4[di] ;; get seg addr
mov bx,6[di] ;; get module screen address
mov dl,al ;; save in dl
tohex ;; convert to hex word
mov es:320[bx],ah ;; put to the screen
mov es:322[bx],al ;; /
dec bx ;; point to led
or dl,dl ;; test for z
mov al,red ;; set up for z
jz next2 ;; branch if z
mov al,red+hi ;; else set up for nz
next2: mov es:[bx],al ;; set the led
next1: sendmb ;; send next midi buffer byte
add si,4 ;; point to next module exe addr
mov di,2[si] ;; set di pointing to variable list
jmp [si] ;; go for it
endm
;--------------------------------------------------------------
; This NEXT is used when the output is to be a one-shot, only
; set hi for one cycle.
; If the output is low when the routine is called, it does nothing.
; If the output is hi, it displays & sends to MIDI, upon the next
; cycle, the output will be set to low.
;
nextt macro
jmp _nextt ;; jump, rather copy the code
endm
;--------------------------------------------------------------
@nextt macro
local next1,next2,next3 ;; labels
mov ax,outn[di] ;; get hi & low byte of output
or al,ah ;; anything there
jz next1 ;; no, easy exit
;;
test ah,-1 ;; 2nd time around?
mov ah,al ;; (set up)
jz next3 ;; no, branch
mov ax,0 ;; yes, zip it
;;
next3: mov outn[di],ax ;; /
mov es,4[di] ;; get seg addr
mov bx,6[di] ;; get module screen address
mov dl,al ;; save in dl
tohex ;; convert to hex word
mov es:320[bx],ah ;; put to the screen
mov es:322[bx],al ;; /
dec bx ;; point to led
or dl,dl ;; test for z
mov al,red ;; set up for z
jz next2 ;; branch if z
mov al,red+hi ;; else set up for nz
next2: mov es:[bx],al ;; set the led
next1: sendmb ;; send next midi buffer byte
add si,4 ;; point to next module exe addr
mov di,2[si] ;; set di pointing to variable list
jmp [si] ;; go for it
endm
;--------------------------------------------------------------
; macro to display a magenta input value
; displays ls byte at value location
; assumes si = 6[di], es = 4[di]
;
showpv macro value
mov al,((value*2)+var0)[di] ;; get the binary value
tohex ;; convert to hex in ax
mov es:((value*160)+480)[si],ah;; put it to the screen
mov es:((value*160)+482)[si],al;; put it to the screen
endm
;--------------------------------------------------------------
; macro to display a magenta input value
; displays ms byte at value location + 1
; assumes si = 6[di], es = 4[di]
;
showpp macro value
mov al,((value*2)+var0+1)[di] ;; get the binary value
tohex ;; convert to hex in ax
mov es:((value*160)+480)[si],ah;; put it to the screen
mov es:((value*160)+482)[si],al;; put it to the screen
endm
;--------------------------------------------------------------
; macro to display a magenta input value, only if value <> value+1
; displays ls byte at value location, sets value = value+1
; assumes si = 6[di], es = 4[di]
;
showpq macro value
local boogie ;; label for exit
mov al,((value*2)+var0)[di] ;; get the binary value
cmp al,((value*2)+var0+1)[di] ;; changed?
jz boogie ;; no, split
mov ((value*2)+var0+1)[di],al ;; set value+1 <-- value
tohex ;; convert to hex in ax
mov es:((value*160)+480)[si],ah;; put it to the screen
mov es:((value*160)+482)[si],al;; put it to the screen
boogie = $
endm