home *** CD-ROM | disk | FTP | other *** search
- TITLE Modules for Modular Sequencer
- NAME MBB
- .SALL
- ;==============================================================
- ; MusicBox Modular Sequencer, Version 2
- ; modules code
- ;--------------------------------------------------------------
- ; author: John Dunn
- ; date: 03/07/86
- ; update: 03/20/88
- ;--------------------------------------------------------------
- ; COPYRIGHT (C) 1986 John Dunn, All Rights Reserved
- ; Entered into the Public Domain, March 20, 1988
- ;
- ; Use and copying of this software and preparation of derivative works
- ; based upon this software are permitted. Any distribution of this
- ; software or derivative works must comply with all applicable United
- ; States export control laws.
- ;
- ; This software is made available AS IS, and the author makes no warranty
- ; about the software, its performance, or its conformity to any specification.
- ;
- ; Any person obtaining a copy of this software is requested to send their
- ; name and address address to:
- ;
- ; John Dunn, Senior Research Fellow
- ; Time Arts Inc.
- ; 3436 Mendocino Ave.
- ; Santa Rosa, CA 95401
- ;
- ;==============================================================
- include order.asm
- ;--------------------------------------------------------------
- include equates.asm
- ;--------------------------------------------------------------
- ;_DATA SEGMENT
- ; ASSUME DS:DGROUP, CS:_TEXT
- ;--------------------------------------------------------------
- extrn _nextv:near,_nextx:near,_nextl:near,_nextt:near
- extrn _doit:near
- ;--------------------------------------------------------------
- extrn ticka:byte,tickis:byte
- extrn _header:byte
- extrn varsav:word,cmdflg:byte,special:word,cmdcnt:byte
- extrn locsav:word,cmdloc:word,vpage:word,curadr:word
- extrn valflg:byte
- extrn @zero:near,magflg:byte,usrflg:byte,holdv:word
- extrn colr:byte
- ;--------------------------------------------------------------
- extrn midisf:byte ; 0=no sync, 1=send sync
- extrn midixsf:byte ; 0=not xtrn sync, NZ=is
- extrn midiok:byte ; 0=off/not init, 2=off&init, 3=on
- extrn mprstf:byte ; master program reset flag
- extrn mpmodf:byte ; master program mode flag
- extrn mpadrf:byte ; nz if change in prog address
- extrn mpadr:byte ; master program address
- extrn mmcount:word ; master measure count
- extrn mmtick:word ; ticks left in current measure
- extrn mmreset:byte ; master measure reset flag
- extrn mmstart:byte ; master measurd start flag
- ;--------------------------------------------------------------
- extrn rseed:word ; random number seed
- extrn rhold:byte ; rng hold flag
- extrn notetbl:byte ; note -> clocks xlate
- extrn notes:word
- extrn interv:byte ; intervals for modulation
- ;
- extrn xcax:word ; register storage, used by xcall
- extrn xcbx:word
- extrn xccx:word
- extrn xcdx:word
- ;
- extrn temp0:byte ; temp storage, use within module
- extrn temp1:byte
- extrn temp2:byte
- extrn temp3:byte
- ;--------------------------------------------------------------
- ; the following are saved/loaded
- ;--------------------------------------------------------------
- extrn mvlsav:abs ; start of mod values to save
- extrn mute:word ; channel mute flags
- extrn mutef:byte ; 1=mute, 0=solo flag
- ;
- extrn mbeat:byte ; master beats/measure
- extrn mnote:byte ; master note value
- extrn mtempo:byte ; master tempo
- extrn mclocks:word ; master clocks/measure
- ;
- extrn ctrlmap:byte ; midi controller map
- extrn pcva:byte ; values sent to controller
- extrn pcvb:byte ; values sent to controller
- extrn pcvc:byte ; values sent to controller
- extrn pcvd:byte ; values sent to controller
- extrn pcve:byte ; values sent to controller
- extrn pcvf:byte ; values sent to controller
- ;
- extrn mvlnum:abs ; number of mod values to save
- ;--------------------------------------------------------------
- ;_DATA ENDS
- ;==============================================================
- ; Module Execution Code
- ; All inputs are word pointers to output word values.
- ; All outputs are binary words, with only the ls byte output.
- ;==============================================================
- ; EQUATES for modules
- ;
- vseg equ 4 ; offset to video seg addr
- vaddr equ 6 ; offset to video page addr
- outn equ 8 ; offset to output
- numvar equ 10 ; number of input variables
- var0 equ 12 ; offset to variable 0
- var1 equ var0+2 ; offset to variable 1
- var2 equ var1+2 ; etc.
- var3 equ var2+2 ; etc.
- var4 equ var3+2 ; etc.
- var5 equ var4+2 ; etc.
- var6 equ var5+2 ; etc.
- var7 equ var6+2 ; etc.
- var8 equ var7+2 ; etc.
- var9 equ var8+2 ; etc.
- var10 equ var9+2 ; etc.
- var11 equ var10+2 ; etc.
- var12 equ var11+2 ; etc.
- var13 equ var12+2 ; etc.
- var14 equ var13+2 ; etc.
- var15 equ var14+2 ; etc.
- var16 equ var15+2 ; etc.
- var17 equ var16+2 ; etc.
- var18 equ var17+2 ; etc.
- var19 equ var18+2 ; etc.
- var20 equ var19+2 ; etc.
- var21 equ var20+2 ; etc.
- var22 equ var21+2 ; etc.
- slewc equ var22 ; programmer slew buffer
- slewd equ slewc+6 ; etc.
- slewe equ slewd+6 ; etc.
- slewf equ slewe+6 ; etc.
- pubuf equ slewf+6 ; programmer undo buffer
- psbuf equ pubuf+13 ; programmer save buffer
- ;
- onflg equ 1 ; bit mask for note-on
- offlg equ 2 ; bit mask for note-off
- sentf equ 4 ; bit mask for note-sent
- ;--------------------------------------------------------------
- _TEXT SEGMENT
- ASSUME CS: _TEXT, DS: DGROUP, SS: DGROUP, ES: NOTHING
- ;--------------------------------------------------------------
- extrn ticks:word,loops:word,seconds:word,secondf:byte
- extrn todec:near,tonote:near,startm:near
- extrn _cancel:near,workx:near,split:near
- extrn turnon:near,turnoff:near
- extrn mstart:byte,mstop:byte,mcont:byte
- extrn allmidi:near
- ;==============================================================
-
- ;==============================================================
- ; THE MODULES
- ;==============================================================
- include macros.asm
- ;==============================================================
- ; generate melody & chord changes from input base & intervals
- ;--------------------------------------------------------------
- ; inputs:
- ; 0: chord array location (16 possible arrays of 4 values)
- ; 1: base input value
- ; 2: 1st interval above base
- ; 3: 2nd interval above base
- ; 4: 3rd interval above base
- ; 5: nz = normalize to octave
- ; 6: offset to base
- ; 7: nz = sort
- ; 8: foldover range
- ; 9: doit strobe
- ; 10x: clock ticks
- ; output: root # (always 0 unless sort)
- ;--------------------------------------------------------------
- public _cgen
- _cgen:
- tick var9,var10 ; clock strobe
- jc cgen0 ; yes, go do it
- jmp cgenz ; exit if no tick
- ;
- cgen0: getv al,var0 ; get array location
- and ax,15 ; mask
- add ax,ax ; *4
- add ax,ax ; /
- add ax,offset dgroup:interv ; add in int table addr
- mov bp,ax ; save in bp
- ;
- getv al,var1 ; get input
- testv var5,-1 ; want to normalize?
- jz cgen1 ; no, branch
- normal ; yes, normalize to octave
- mov al,ah ; put back in al
- ;
- cgen1: getv ah,var6 ; get offset
- add al,ah ; add to root
- ;
- getv ah,var2 ; add intervals to root
- add ah,al ; /
- getv dl,var3 ; /
- add dl,al ; /
- getv dh,var4 ; /
- add dh,al ; /
- ;
- mov byte ptr outn[di],0 ; root is 0
- testv var7,-1 ; want to sort
- jnz cgen4 ; yes, do it
- jmp cgenx ; no, exit
- ;
- cgen4: push ax ; save root
- getv al,var8 ; get max octave range
- and al,15 ; limit
- mov ch,12 ; /
- mul ch ; /
- add ch,al ; ch = range
- pop ax ; restore root
- ;
- range al,ch ; put in range
- range ah,ch ; put in range
- range dl,ch ; put in range
- range dh,ch ; put in range
- ;
- mov cl,al ; save root in cl
- sort4 ; sort
- mov ch,0 ; look for root
- cmp al,cl ; /
- jz cgen3 ; /
- inc ch ; /
- cmp ah,cl ; /
- jz cgen3 ; /
- inc ch ; /
- cmp dl,cl ; /
- jz cgen3 ; /
- inc ch ; /
- cgen3: mov byte ptr outn[di],ch ; send root # to output
- ;
- cgenx: mov ds:[bp],ax ; set chord values
- mov ds:2[bp],dx ; /
- cgenz: nextv ; exit
- ;==============================================================
- ; set new chords table data from 4 inputs
- ;--------------------------------------------------------------
- ; inputs:
- ; 0: chord array location (16 possible arrays of 4 values)
- ; 1: root input
- ; 2: 1st interval input
- ; 3: 2nd interval input
- ; 4: 3rd interval input
- ; 5: nz = normalize to octave
- ; 6: offset to base
- ; 7: nz = sort
- ; 8: foldover range
- ; 9: doit strobe
- ; 10x: clock ticks
- ; output: root # (always 0 unless sort)
- ;--------------------------------------------------------------
- public _cmak
- _cmak:
- tick var9,var10 ; clock strobe
- jc cmak0 ; yes, go do it
- jmp cmakz ; exit if no tick
- ;
- cmak0: getv al,var0 ; get array location
- and ax,15 ; mask
- add ax,ax ; *4
- add ax,ax ; /
- add ax,offset dgroup:interv ; add in int table addr
- mov bp,ax ; save in bp
- ;
- getv cl,var6 ; get offset
- getv al,var1 ; get inputs
- add al,cl ; add offset
- getv ah,var2 ; /
- add ah,cl ; /
- getv dl,var3 ; /
- add dl,cl ; /
- getv dh,var4 ; /
- add dh,cl ; /
- ;
- testv var5,-1 ; want to normalize?
- jz cmak1 ; no, branch
- mov cx,ax ; yes, save ax
- mov bx,dx ; save dx
- normal ; normalize
- mov cl,ah ; /
- mov al,ch ; /
- normal ; /
- mov ch,ah ; /
- mov al,bl ; /
- normal ; /
- mov bl,ah ; /
- mov al,bh ; /
- normal ; /
- mov bh,ah ; /
- mov ax,cx ; restore to ax,dx
- mov dx,bx ; /
- ;
- cmak1: mov byte ptr outn[di],0 ; root is 0
- testv var7,-1 ; want to sort
- jnz cmak4 ; yes, do it
- jmp cmakx ; no, exit
- ;
- cmak4: push ax ; save root
- getv al,var8 ; get max octave range
- and al,15 ; limit
- mov ch,12 ; /
- mul ch ; /
- add ch,al ; ch = range
- pop ax ; restore root
- ;
- range al,ch ; put in range
- range ah,ch ; put in range
- range dl,ch ; put in range
- range dh,ch ; put in range
- ;
- mov cl,al ; save root in cl
- sort4 ; sort
- mov ch,0 ; look for root
- cmp al,cl ; /
- jz cmak3 ; /
- inc ch ; /
- cmp ah,cl ; /
- jz cmak3 ; /
- inc ch ; /
- cmp dl,cl ; /
- jz cmak3 ; /
- inc ch ; /
- cmak3: mov byte ptr outn[di],ch ; send root # to output
- ;
- cmakx: mov ds:[bp],ax ; set chord values
- mov ds:2[bp],dx ; /
- cmakz: nextv ; exit
- ;==============================================================
- ; select interval from modulated interval table
- ; inputs:
- ; 0: clock
- ; 1: location
- ; 2: interval step
- ; 3: nz = sort
- ; 4: offset
- ; 5x: clock tick
- ; output: note interval
- ;--------------------------------------------------------------
- public _cplay,_cplai
- _cplai: nop ; 2 sets of modules
- _cplay: tick var0,var5 ; clock
- jnc cplayz ; branch if no tick
- getv cl,var1 ; get interval address
- and cx,15 ; mask
- add cx,cx ; *4
- add cx,cx ; /
- add cx,offset dgroup:interv ; cx = interval address
- ;
- testv var3,-1 ; wanna sort?
- jz cplay1 ; no, branch
- ;
- mov bx,cx ; pick up intervals
- mov ax,[bx] ; /
- mov dx,2[bx] ; /
- sort4 ; sort them
- mov word ptr temp0,ax ; put in temp array
- mov word ptr temp2,dx ; /
- mov cx,offset dgroup:temp0 ; cx = sorted interval addr
- ;
- cplay1: getv bl,var2 ; get interval number
- and bx,3 ; mask
- add bx,cx ; bx = table index
- mov al,[bx] ; get the interval
- ;
- getv ah,var4 ; get offset
- add al,ah ; add offset to interval
- putn al ; send it out
- cplayz: nextv ; exit
- ;==============================================================
- ; store value to interval table
- ; inputs:
- ; 0: chord array location (16 possible arrays of 4 values)
- ; 1: location in array
- ; 2: base input value
- ; 3: nz = normalize to octave
- ; 4: offset to base
- ; 5: doit strobe
- ; 6x: clock tick
- ;
- ; output: previous value at address
- ;--------------------------------------------------------------
- public _cstor
- _cstor: tick var5,var6 ; strobe?
- jnc cstorz ; no, exit
- ;
- getv al,var2 ; get input
- testv var3,-1 ; want to normalize?
- jz cstor1 ; no, branch
- normal ; yes, normalize to octave
- mov al,ah ; put back in al
- ;
- cstor1: getv ah,var4 ; get offset
- add al,ah ; add to input
- ;
- getv cl,var0 ; get interval address
- and cx,15 ; mask
- add cx,cx ; *4
- add cx,cx ; /
- add cx,offset dgroup:interv ; cx = interval address
- ;
- getv bl,var1 ; get interval number
- and bx,3 ; mask
- add bx,cx ; bx = table index
- ;
- xchg al,[bx] ; swap old with new
- putn al ; send old to output
- cstorz: nextv ; exit
- ;==============================================================
- ; generate bass note line, dithered input a,b
- ; inputs:
- ; 0: clock
- ; 1: nz = hold
- ; 2: strobe center to output
- ; 3: center
- ; 4: max distance from center
- ; 5: nz = use -, z = use +
- ; 6: input "a"
- ; 7: input "b"
- ; 8x:
- ; 8z: clock tick, init flag
- ; output: new bass note
- ;--------------------------------------------------------------
- public _bassd
- _bassd:
- tickb1 var2,var8+1 ; strobe clock?
- jnc bassd4 ; branch if no strobe
- and byte ptr var8+1[di],0fbh; yes, flag/auto initialize
- bassd4: tick var0,var8+1 ; wait for clock tick
- jnc bassdz ; exit if not clock
- hold var1 ; hold?
- jnz bassdz ; exit if hold
- ;
- test byte ptr var8+1[di],4 ; was flag set?
- jnz bassd1 ; no, branch
- or byte ptr var8+1[di],4 ; yes, clear flag
- bassd0: getv al,var3 ; get the input
- putn al ; send it to output
- jmp short bassdz ; exit
- ;
- bassd1: getv al,var6 ; load for "a"
- testv var5,-1 ; test for +/-
- jz bassd2 ; branch if +
- getv al,var7 ; load for "b"
- neg al ; make "b" -
- bassd2: add outn[di],al ; add the offset
- ;
- getv al,var3 ; get center
- getv ah,var4 ; get max
- mov dl,al ; test for upper limit
- add dl,ah ; /
- cmp dl,outn[di] ; /
- jb bassd0 ; reset if above limit
- sub al,ah ; test for lower limit
- cmp outn[di],al ; /
- jb bassd0 ; reset if below limit
- bassdz: nextv ; exit
- ;==============================================================
- ; Bit Formatter
- ; inputs: 1 - 8: bit set inputs, zero clrs, nz sets
- ; output: byte formatted from the 8 inputs
- ;--------------------------------------------------------------
- public _gout
- _gout:
- gettag ; es:bx = screen addr of tag
- dec bx ; point to leds
- add bx,480 ; point to the first bit led
- mov ax,bx ; ax = screen address pointer
- mov bp,var0 ; bp = addr of first variable
- mov dx,100H ; dl=0, dh=1
- mov cx,8 ; gonna do 8 bits
- gout1: mov bx,ds:[bp+di] ; get the variable address
- cmp byte ptr [bx],0 ; test for zero/not zero
- mov bx,ax ; get screen address
- jnz gout2 ; branch if not zero
- mov byte ptr es:[bx],yellow; turn off the led
- jmp short gout3 ; branch to finish up
- gout2: mov byte ptr es:[bx],hi+red; turn on the led
- or dl,dh ; set the bit
- gout3: shl dh,1 ; bump bit flag
- add ax,160 ; bump screen addr 1 line
- add bp,2 ; bump variable pointer
- loop gout1 ; loop til done
- putn dl ; set the new byte value
- nextv ; exit w screen update
- ;==============================================================
- ; Display bits in a byte as gate lites
- ; inputs: 0: byte
- ; output: none
- ;--------------------------------------------------------------
- public _gatel
- _gatel:
- getv al,var0 ; get the byte
- gettag ; es:bx = screen addr of tag
- dec bx ; point to leds
- add bx,480 ; point to the first bit led
- mov cx,8 ; 8 bits to do
- gatel1: shr al,1 ; bit --> cy
- jc gatel2 ; branch if the bit is hi
- and byte ptr es:[bx],7; turn the led off
- jmp short gatel3 ; branch
- gatel2: or byte ptr es:[bx],8; turn the led on
- gatel3: add bx,160 ; go down 1 line
- loop gatel1 ; do all 8 bits
- nextx ; exit quiet
-
- ;==============================================================
- ; Display values as an indicator bar
- ; linear display
- ; inputs: 0: left row, 1: right 2: scale
- ; 3x: left save, 3z: right save
- ; output: none
- ;--------------------------------------------------------------
- public _imeter
- _imeter:
- getv al,var0 ; al = left value
- getv dl,var1 ; dl = right value
- getv dh,var2 ; dh = scale
- or dh,dh ; scale = 0?
- jnz imeter0 ; no, branch
- inc dh ; yes, start with 1
- imeter0:mov es,4[di] ; get seg addr
- mov bx,6[di] ; get module screen address
- add bx,160*5 ; point to top row of leds
- ;
- inc bx ; point to left leds
- cmp al,var3[di] ; has left changed
- jz imeter4 ; no, branch
- mov var3[di],al ; yes, save new value
- push dx ; save right value & scale
- or al,al ; al = 0 ?
- jz imeter7 ; yes, don't divide
- mov ah,0 ; ax = left value
- div dh ; al = ax/dl
- imeter7:call imeter1 ; show the new value
- pop dx ; restore right value & scale
- imeter4:add bx,2 ; point to right column
- cmp dl,var3+1[di] ; did middle change
- jz imeter6 ; no, branch
- mov var3+1[di],dl ; yes, save the new value
- mov al,dl ; al = right value
- or al,al ; al = 0 ?
- jz imeter8 ; yes, don't divide
- mov ah,0 ; ax = left value
- div dh ; al = ax/dl
- imeter8:call imeter1 ; show the new value
- imeter6:nextx ; exit quiet
-
- ;--------------------------------------------------------------
- ; convert linear 0-8 to log bit position
- ; then jump to emeter1 to display
- ; call with al = value
- ;
- imeter1:test al,0f8h ; if > 7, max out
- jz imeter2 ; /
- mov dl,-1 ; /
- jmp short imeter3 ; /
- imeter2:mov cl,al ; else convert
- xor al,al ; /
- stc ; /
- rcl al,cl ; /
- mov dl,al ; /
- imeter3:jmp emeter1 ; display
-
- ;==============================================================
- ; Display values as an indicator bar
- ; inputs: 0: left row, 1: right 2: scale
- ; 3x: left save, 3z: right save
- ; output: none
- ;--------------------------------------------------------------
- public _emeter
- _emeter:
- getv al,var0 ; al = left value
- getv dl,var1 ; dl = right value
- getv dh,var2 ; dh = multiplier
- or dh,dh ; mult = 0?
- jnz emeter0 ; no, branch
- inc dh ; yes, start with 1
- emeter0:mov es,4[di] ; get seg addr
- mov bx,6[di] ; get module screen address
- add bx,160*5 ; point to top row of leds
- ;
- inc bx ; point to left leds
- cmp al,var3[di] ; has left changed
- jz emeter4 ; no, branch
- mov var3[di],al ; yes, save new value
- push dx ; save right value & mult
- mul dh ; ax = bumped right value
- or ah,ah ; > 255 ?
- jz emeter5 ; no, branch
- mov al,255 ; yes, make it 255
- emeter5:mov dl,al ; set up for display
- call emeter1 ; show the new value
- pop dx ; restore right value & scale
- emeter4:add bx,2 ; point to right column
- mov al,dl ; al = right value
- cmp al,var3+1[di] ; did right change
- jz emeter6 ; no, branch
- mov var3+1[di],al ; yes, save the new value
- mul dh ; ax = bumped right value
- or ah,ah ; > 255 ?
- jz emeter7 ; no, branch
- mov al,255 ; yes, make it 255
- emeter7:mov dl,al ; set up for display
- call emeter1 ; show the new value
- emeter6:nextx ; exit quiet
-
- ;--------------------------------------------------------------
- ; subroutine to show a column of leds
- ; call with BX = address of top of column (preserved), DL = value
- ; display is log, sets top led high and all following if
- ; bit 7 is set, else sets top led low, then top-1 if bit 6, etc.
- ;
- emeter1:push bx ; preserve bx
- mov dh,0 ; use dh as flag byte
- mov cx,8 ; 8 leds in the column
- emeterl:shl dx,1 ; bump hi bit of dl into dh
- test dh,-1 ; on or off?
- jz emeter2 ; branch if off
- or byte ptr es:[bx],8 ; make bright
- jmp short emeter3 ; duck
- emeter2:and byte ptr es:[bx],0f7h ; or make dark
- emeter3:add bx,160 ; next line
- loop emeterl ; loop til done
- pop bx ; restore bx
- ret ; exit
- ;==============================================================
- ; Set output to approximately the same as input, within limits
- ; inputs: 0: input 1: upper limit, 2: lower limit,
- ; 3x: last input
- ; output: scaled random number
- ;--------------------------------------------------------------
- public _apprx
- _apprx:
- getv dl,var0 ; get the value
- test rhold,-1 ; branch if alpha seed
- jnz appr1 ; /
- cmp dl,var3[di] ; same as last?
- jnz appr1 ; no, go to work
- nextx ; yes, easy exit
- ;
- appr1: mov var3[di],dl ; set new value
- random
- getv al,var1 ; get upper offset
- inc al ; fudge
- add al,dl ; add in value
- mov ah,0 ; msb = 0
- getv bl,var2 ; get lower offset
- sub dl,bl ; subtract from value
- mov bl,dl ; keep it in bl
- mov bh,0 ; msb = 0
- sub ax,bx ; ax = upper - lower
- mul cx ; dx = appr * (upper-lower)/10000H
- add dx,bx ; dx = above + lower
- putn dl ; send it out
- nextv ; exit with video update
- ;==============================================================
- ; Generate random numbers
- ; inputs: 0: clock 1: hold 2: seed value, 3: range, 4: offset,
- ; 5: seed, 6x: saved value, 6z: clock-tick
- ; output: random number
- ;--------------------------------------------------------------
- public _rand
- _rand:
- mov ah,var6[di] ; get last value
- ;
- getv al,var1 ; local hold?
- or al,rhold ; global rand hold?
- jz rand0 ; no, branch
- rand2: getv al,var2 ; yes, reset seed
- mov ah,al ; /
- mov var5[di],ax ; /
- jmp rand1a ; go out
- ;
- rand0: test mprstf,-1 ; master hold?
- jnz rand1 ; yes, branch
- ;
- tick var0,var6+1 ; clock tick
- jnc rand1 ; branch if no tick
- ;
- mov cx,var5[di] ;; get next raw seed
- add cx,9248H ;; /
- ror cx,1 ;; /
- ror cx,1 ;; /
- ror cx,1 ;; /
- mov var5[di],cx ;; /
- ;
- getv al,var3 ; get range
- mul cl ; ah = rand * range /256
- rand1a: mov var6[di],ah ; put it away
- rand1: getv al,var4 ; get offset
- add al,ah ; put them together
- putn al ; send it out
- nextv ; exit
- ;==============================================================
- ; Non-repeating random pattern
- ; inputs: 0: clock 1: hold 2: seed value, 3: inc/dec, 4: range
- ; 5x: saved value, 5z: clock-tick, 6: address pointer
- ; output: random number
- ;--------------------------------------------------------------
- public _rrand
- _rrand:
- getv cl,var4 ; get range
- cmp cl,1 ; check for 0,1
- jna rrand0 ; split if 0
- mov dx,1 ; for inc/dec
- testv var3,-1 ; dec if nz
- jz rrand03 ; /
- mov dx,-1 ; /
- ;
- rrand03:
- getv al,var1 ; local hold?
- or al,rhold ; global rand hold?
- jz rrand01 ; no, branch
- rrand2: getv al,var2 ; yes, get seed
- putn al ; send it out
- mov ah,64 ; /
- mul ah ; /
- mov var6[di],ax ; /
- jmp rrandx ; split
- ;
- rrand01:test mprstf,-1 ; master hold?
- jnz rrand0 ; yes, branch
- ;
- tick var0,var5+1 ; clock tick
- jc rrand1 ; branch if tick
- rrand0: nextx ; else just split
- ;
- rrand1: add var6[di],dx ; bump pointer
- rrandz: mov bx,var6[di] ; get it
- and bx,3fffh ; keep in code range
- add bx,offset _doit ; start of code
- mov ax,cs:[bx] ; get the byte
- add al,ah ; fill it out
- mul cl ; ah = rand * range /256
- cmp ah,var5[di] ; same as last?
- jz rrand1 ; yes, do it again
- mov var5[di],ah ; no, save it
- putn ah ; send it out
- rrandx: nextv ; exit
- ;==============================================================
- ; Random strobe generator
- ; output: 50% strobe
- ; input: 0: strobe, 1x: clock tick
- ;--------------------------------------------------------------
- public _randp
- _randp:
- mov cl,0 ; setup for hold
- test mprstf,-1 ; check alpha hold
- jnz randpx ; yes, exit
- tick var0,var1 ; clock input
- jnc randpz ; exit if no clock
- random ; get random value
- and cl,1 ; isolate lsb
- randpx: putn cl ; send it our
- randpz: nextl ; show it
- ;==============================================================
- ; Random strobe generator
- ; output: clock strobe
- ; input: 0: reset, 1: count, 2: offset 3: dither
- ; 4x:countdown timer, 4z: copy of count
- ;--------------------------------------------------------------
- public _nrand
- _nrand: testv var1,-1 ; clock = 0
- jz nrandz ; yes, just exit
- hold var0 ; hold?
- jz nrand0 ; no, branch
- mov al,byte ptr cs:loops; get count
- and al,1 ; /
- mov var4[di],al ; reset clock counters
- jmp short nrandz ; split
- ;
- nrand0: getv ah,var1 ; get current count
- cmp ah,var4+1[di] ; same as before?
- jz nrand1 ; yes, branch
- cmp ah,1 ; set to 1?
- jnz nrand3 ; no, branch
- mov ah,2 ; yes, set to 2
- nrand3: mov al,byte ptr cs:loops; get count
- and al,1 ; /
- mov var4[di],ax ; /
- ;
- nrand1: getv al,var2 ; get offset trigger
- cmp al,ah ; out of range?
- jb nrand4 ; no, branch
- mov al,0 ; yes, zip it
- nrand4: cmp al,var4[di] ; same as count?
- jnz nrand2 ; no, branch
- random ; yes, get random value
- getv ch,var3 ; get ddithr value
- sub ch,cl ; above threshold?
- jna nrand2 ; no, branch
- mov byte ptr outn[di],1; else output flag
- ;
- nrand2: inc byte ptr var4[di]; tick
- cmp ah,var4[di] ; reached count?
- jnz nrandz ; no, exit
- mov byte ptr var4[di],0; yes, reset timer
- nrandz: nextt ; exit
- ;==============================================================
- ; Random slope output
- ; inputs 0: count, 1: range,
- ; 2x: target, 2+:
- ; 3x: current, 3+: +/-
- ; 4x: clock, 4+: old clock
- ;
- ; ouput last +/- 1
- ;--------------------------------------------------------------
- public _variz,_variy
- _variy: nop
- _variz:
- getv dh,var1 ; get range input
- getv al,var0 ; get clock
- ;
- test dh,80H ; test msb of range for reset
- jnz varizz ; go reset if high
- ;
- test mprstf,-1 ; check for master reset
- jnz varizz ; reset if high
- ;
- test rhold,-1 ; check for random reset
- jnz varizz ; reset if high
- ;
- cmp al,var4+1[di] ; clock same as before
- jz variz0 ; yes, go to work
- jmp varizk ; no, fix clock
- ;--------------------------------------------------------------
- varizz: and dh,7fh ; strip msb
- putn dh ; send it out
- mov var2[di],dh ; set as target
- mov byte ptr var3+1[di],1 ; set to count up
- shr dh,1 ; current is range/2
- shr dh,1 ; current is range/2
- mov var3[di],dh ; /
- ;
- varizk: mov var4+1[di],al ; save clock
- mov byte ptr var4[di],1 ; new one next clock
- nextv ; split
- ;--------------------------------------------------------------
- varizzx:nextx ; split
- variz0: dec byte ptr var4[di] ; bump clock
- jnz varizzx ; exit if not 0
- getv al,var0 ; else get it
- mov var4+1[di],al ; save clock
- inc al ; bump
- mov var4[di],al ; put away
- ;--------------------------------------------------------------
- mov dl,var3[di] ; get current value
- add dl,var3+1[di] ; add bump
- mov var3[di],dl ; put it away
- cmp dl,var2[di] ; reached target?
- jnz variz2 ; no, branch
- ;
- variz1: random ; get new rand
- mov al,dh ; get range
- test ch,0E0H ; 3/4 of the time
- jz variz1a ; ... use it straight
- rcr cl,1 ; ... else cut 1/2
- jnc variz1a ; ... and maybe more
- shr cl,1 ; ... cut again
- variz1a:mul cl ; ah = rand * range /256
- ;
- mov byte ptr var3+1[di],0ffh; set up for inc
- cmp ah,var2[di] ; is it < target?
- jb variz3 ; yes,is <, exit
- mov byte ptr var3+1[di],1 ; no, set up for dec
- jnz variz3 ; exit if <>
- inc ah ; else bump
- variz3:
- mov var2[di],ah ; save new target
- variz2:
- shr dh,1 ; calc offset
- shr dh,1 ; calc offset
- add dl,dh ; add in count
- jns variz2a ; branch if <= 7fh
- mov dl,7fh ; else make 7fh
- variz2a:putn dl ; send it out
- nextv ; exit
- ;==============================================================
- ; Random slope output
- ; inputs 0: clock 1: hold, 2: range 3: offset
- ; 4x: +/- 4+: clock tick, 5x: target, 5+: current
- ; ouput last +/- 1
- ;--------------------------------------------------------------
- public _variv
- _variv:
- test rhold,-1 ; check for random reset
- jnz variv00 ; reset if high
- ;
- hold var1 ; hold?
- jz variv0 ; no, branch
- variv00:mov ah,var5+1[di] ; yes, get current
- getv al,var3 ; get offset
- add al,ah ; put them together
- putn al ; send it
- ;
- inc ah ; bump current
- mov var5[di],ah ; set up target
- mov byte ptr var4[di],1 ; set up counter
- nextv ; exit
- ;--------------------------------------------------------------
- variv0:
- tick var0,var4+1 ; clock tick
- jc variv1 ; branch if tick
- nextx ; else just exit
- ;--------------------------------------------------------------
- variv1: mov dl,var5+1[di] ; get current value
- add dl,var4[di] ; add bump
- mov var5+1[di],dl ; put it away
- cmp dl,var5[di] ; reached target?
- jnz variv2 ; no, branch
- ;
- random ; else get new rand
- getv al,var2 ; get range
- mul cl ; ah = rand * range /256
- ;
- mov byte ptr var4[di],-1 ; set up for inc
- cmp ah,var5[di] ; is it < target?
- jb variv3 ; yes,is <, exit
- mov byte ptr var4[di],1 ; no, set up for dec
- jnz variv3 ; exit if <>
- inc ah ; else bump
- variv3:
- mov var5[di],ah ; save new target
- variv2:
- getv al,var3 ; get offset
- add al,dl ; add current
- putn al ; send it out
- nextv ; exit
- ;==============================================================
- ; Random slope output
- ; inputs 0: clock
- ; 1: hold
- ; 2: addamt
- ; 3: range
- ; 4: offset
- ; 5x: target
- ; 6x: count
- ; 6+: b7=sign, b0=clock tick
- ;
- ; output: count+offset
- ;--------------------------------------------------------------
- public _varix
- _varix:
- test rhold,-1 ; check for random reset
- jnz varix00 ; reset if high
- ;
- hold var1 ; hold?
- jz varix0 ; no, branch
- varix00:mov byte ptr var6[di],0 ; yes count = 0
- mov byte ptr var5[di],0 ; target = 1
- and byte ptr var6+1[di],7FH ; set sign bit
- varixz: jmp varixx ; exit w count+offset
- ;--------------------------------------------------------------
- varix0:
- tick var0,var6+1 ; clock tick
- jc varix1 ; branch if tick
- nextx ; else just exit
- ;--------------------------------------------------------------
- varix1: getv al,var2 ; get add ammt
- getv ah,var3 ; is add amb > range
- cmp al,ah ; add amt - range
- jnb varixz ; yes, just exit
- ;
- mov ah,0 ; ax = add amt
- mov dl,var6[di] ; get count
- mov dh,0 ; dx = count
- ;
- test byte ptr var6+1[di],80H ; sign = count down?
- jnz varix1a ; yes, branch
- ;
- add dx,ax ; dx = count + add amt
- mov al,var5[di] ; get target
- mov ah,0 ; ax = target
- cmp ax,dx ; target - new count
- jnb varix4 ; send if target > nc
- jmp varix2 ; else get a new one
- ;--------------------------------------------------------------
- varix1a:sub dx,ax ; dx = count - add amt
- jnc varix1b ; make 0 if underflow
- mov dx,0 ; /
- varix1b:mov al,var5[di] ; get target
- mov ah,0 ; ax = target
- cmp ax,dx ; target - new count
- jna varix4 ; send if target < nc
- ; jmp varix2 ; else get a new one
- ;--------------------------------------------------------------
- varix2: random ; else get new rand
- getv al,var3 ; get range
- or al,al ; exit if range=0
- jz varixx ; /
- mul cl ; ah = rand * range /256
- or ah,ah ; don't want 0
- jz varix2 ; /
- xchg var5[di],ah ; save new target
- mov var6[di],ah ; set count to old target
- cmp ah,var5[di] ; old - new
- ja varix2a ; old > new, go count down
- ;
- and byte ptr var6+1[di],7FH ; clear sign
- getv al,var2 ; get add ammt
- mov ah,0 ; ax = add amt
- mov dl,var6[di] ; get count
- mov dh,0 ; dx = count
- add dx,ax ; dx = count + add amt
- jmp varix4 ; go with dl = new count
- ;
- varix2a:or byte ptr var6+1[di],80H ; set sign
- getv al,var2 ; get add ammt
- mov ah,0 ; ax = add amt
- mov dl,var6[di] ; get count
- mov dh,0 ; dx = count
- sub dx,ax ; dx = count - add amt
- jnc varix4 ; make 0 if underflow
- mov dl,0 ; /
- ;--------------------------------------------------------------
- varix4: mov var6[di],dl ; save new count
- varixx: getv al,var4 ; get offset
- add al,var6[di] ; add count
- putn al ; send it out
- nextv ; exit
- ;==============================================================
- ; Generate a random tone row of 0-11
- ; inputs: 0: address
- ; 1: strobe
- ; 2x: tick
- ; 3-9:tone row table
- ; output: addressed value of tone row (0-11)
- ;--------------------------------------------------------------
- public _trand
- _trand:
- test rhold,-1 ; check for random reset
- jnz trand1 ; branch if high
- ;
- tick var1,var2 ; clock tick
- jnc trand1 ; branch if no tick
- ;
- mov cx,12 ; 12 to do
- mov bp,0 ; set up base
- trand3: mov bx,0 ; set up index
- test rhold,-1 ; holding?
- jz trand7 ; no, get rand
- mov dx,bp ; yes, do 0-1
- jmp short trand2 ; get on with it
- ;
- trand7: randdx ; get rng
- and dl,15 ; 0-15 allowed
- cmp dl,12 ; really 0-11
- jb trand2 ; branch if ok
- shr dl,1 ; else /2
- ;
- trand2: cmp bx,bp ; at the target?
- jnz trand4 ; no, branch
- mov var3[bx+di],dl ; yes, put the byte away
- trand6: inc bp ; bump index
- loop trand3 ; do all 12
- jmp short trand1 ; exit when done
- ;
- trand4: cmp var3[bx+di],dl ; already got?
- jz trand3 ; yes, try again
- inc bx ; no, look at next
- jmp short trand2 ; /
- ;
- trand1: getv bl,var0 ; get address
- mov bh,0 ; make into word
- cmp bl,12 ; keep within range
- jb trand0 ; branch if ok
- ;
- mov ax,bx ; else mod 12
- mov dl,12 ; /
- div dl ; /
- mov bl,ah ; /
- ;
- trand0: mov al,var3[bx+di] ; pick up the byte
- putn al ; send it out
- nextv ; exit
- ;==============================================================
- ; Generate raw binary odds
- ; inputs: 0: clock 1x: clock-tick
- ; output: 0-7; 0 @ 1:2, 1 @ 1:4, ... 7 @ 1:256
- ;--------------------------------------------------------------
- public _oddz
- _oddz:
- tick var0,var1 ; clock tick
- jc oddz1 ; branch if there is a tick
- nextx ; else exit easy
- oddz1: random
- mov al,0 ; output is 0-7
- rol cl,1 ; test msb
- jc oddzx ; branch if set
- inc al ; else bump value
- rol cl,1 ; test msb
- jc oddzx ; branch if set
- inc al ; else bump value
- rol cl,1 ; test msb
- jc oddzx ; branch if set
- inc al ; else bump value
- rol cl,1 ; test msb
- jc oddzx ; branch if set
- inc al ; else bump value
- rol cl,1 ; test msb
- jc oddzx ; branch if set
- inc al ; else bump value
- rol cl,1 ; test msb
- jc oddzx ; branch if set
- inc al ; else bump value
- rol cl,1 ; test msb
- jc oddzx ; branch if set
- inc al ; else bump value
- rol cl,1 ; test msb
- jc oddzx ; branch if set
- xor al,al ; else clr value
- oddzx: putn al ; send it out
- nextv ; exit
- ;==============================================================
- ; dither between 4 inputs
- ; inputs: 0: clock, 1-4: inputs, 5: offset, 6x: clock
- ; output: one of the 4 inputs
- ;--------------------------------------------------------------
- public _odds
- _odds:
- test rhold,-1 ; branch if alpha seed
- jnz odds1 ; /
- tick var0,var6 ; clock tick
- jc odds1 ; branch if there is a tick
- oddsz: nextx ; else exit easy
- odds1: random
- test cl,80H ; 1:2 is input1
- jz odds2 ; /
- getv al,var1 ; /
- jmp short oddsx ; /
- odds2: test cl,40H ; 1:4 is input2
- jz odds3 ; /
- getv al,var2 ; /
- jmp short oddsx ; /
- odds3: test cl,20H ; 1:8 is input3
- jz odds4 ; /
- getv al,var3 ; /
- jmp short oddsx ; /
- odds4: test cl,10H ; 1:16 is input4
- jz oddsz ; else no change
- getv al,var4 ; /
- ;
- oddsx: getv ah,var5 ; get the offset
- add al,ah ; add to input
- putn al ; send it out
- nextv ; exit with video update
- ;==============================================================
- ; dither between 2 inputs
- ; inputs: 0: clock, 1: dither, 2,3 inputs, 4: offset, 5x: clock
- ; output: one of the 2 inputs
- ;--------------------------------------------------------------
- public _dither
- _dither:
- test rhold,-1 ; branch if alpha seed
- jnz dither1 ; /
- tick var0,var5 ; clock tick
- jc dither1 ; branch if there is a tick
- ditherz:nextx ; else exit easy
- dither1:random
- ;
- dither2:getv ch,var1 ; get dither value
- sub ch,cl ; above threshold?
- jna dither3 ; no, branch
- getv al,var3 ; yes, get "b" input
- jmp short ditherx ; split
- dither3:getv al,var2 ; no, get "a" input
- ditherx:getv ah,var4 ; get the offset
- add al,ah ; add to input
- putn al ; send it out
- nextv ; exit with video update
- ;==============================================================
- ; dither between and input and 0
- ; inputs: 0: clock, 1: dither, 2: input, 3: offset, 4x: clock
- ; output: the input or 0
- ;--------------------------------------------------------------
- public _dithzr
- _dithzr:
- test rhold,-1 ; branch if alpha seed
- jnz dithzr1 ; /
- tick var0,var4 ; clock tick
- jc dithzr1 ; branch if there is a tick
- dithzrz:nextx ; else exit easy
- dithzr1:random
- ;
- dithzr2:getv ch,var1 ; get dithzr value
- sub ch,cl ; above threshold?
- jna dithzr3 ; yes, branch
- getv al,var2 ; no, get the input
- jmp short dithzrx ; split
- dithzr3:mov al,0 ; no, make it 0
- dithzrx:getv ah,var3 ; get the offset
- add al,ah ; add to input
- putn al ; send it out
- nextv ; exit with video update
- ;==============================================================
- ; dither between 0 and 1
- ; inputs: 0: clock, 1: dither, 2x: clock
- ; output: 0/1
- ;--------------------------------------------------------------
- public _ddithr
- _ddithr:
- test rhold,-1 ; branch if alpha seed
- jnz ddithr1 ; /
- tick var0,var2 ; clock tick
- jc ddithr1 ; branch if there is a tick
- ddithrz:nextx ; else exit easy
- ddithr1:random
- ddithr2:getv ch,var1 ; get ddithr value
- sub ch,cl ; above threshold?
- mov al,1 ; set flag
- ja ddithrx ; yes, branch branch
- dec al ; no, clear flag
- ddithrx:putn al ; send it out
- nextl ; exit with video update
- ;==============================================================
- ; calc given ratio based on clock input
- ; inputs: 0: master clock
- ; 1-4: clock inputs
- ; 5x: clock ticks
- ; 5z: storage for output until tick
- ; output: 0-F, based on input pattern
- ;--------------------------------------------------------------
- public _ratio
- _ratio:
- mov al,var5+1[di] ; get current output
- tick var1,var5 ; clock tick
- jnc ratio1 ; branch if no tick
- xor al,1 ; else flip the bit
- ratio1: tickb1 var2,var5 ; clock tick
- jnc ratio2 ; branch if no tick
- xor al,2 ; else flip the bit
- ratio2: tickb2 var3,var5 ; clock tick
- jnc ratio3 ; branch if no tick
- xor al,4 ; else flip the bit
- ratio3: tickb3 var4,var5 ; clock tick
- jnc ratio4 ; branch if no tick
- xor al,8 ; else flip the bit
- ratio4: mov var5+1[di],al ; put it away
- tickb4 var0,var5 ; master clock tick?
- jnc ratioz ; no, exit
- putn al ; yes, send out new tick
- ratioz: nextv ; exit with video update
- ;==============================================================
- ; calc given ratio based on dither input
- ; inputs: 0: clock
- ; 1-4: dither levels
- ; 5x: clock tick
- ; output: 0-F, based on input pattern
- ;--------------------------------------------------------------
- public _ratiz
- _ratiz:
- test rhold,-1 ; branch if alpha seed
- jnz ratiz0 ; /
- tick var0,var5 ; tick?
- jc ratiz0 ; yes, branch
- jmp ratizz ; no, just exit
- ratiz0: mov al,outn[di] ; get current output
- random
- getv ch,var1 ; get ddithr value
- or ch,ch ; anything there
- jnz ratiza ; yes, branch
- and al,0feh ; no, clear the bit
- ratiza: sub ch,cl ; above threshold?
- jna ratiz1 ; no, branch
- xor al,1 ; yes, set flag
- ratiz1: random
- getv ch,var2 ; get ddithr value
- or ch,ch ; anything there
- jnz ratizb ; yes, branch
- and al,0fdh ; no, clear the bit
- ratizb: sub ch,cl ; above threshold?
- jna ratiz2 ; no, branch
- xor al,2 ; yes, set flag
- ratiz2: random
- getv ch,var3 ; get ddithr value
- or ch,ch ; anything there
- jnz ratizc ; yes, branch
- and al,0fbh ; no, clear the bit
- ratizc: sub ch,cl ; above threshold?
- jna ratiz3 ; no, branch
- xor al,4 ; yes, set flag
- ratiz3: random
- getv ch,var4 ; get ddithr value
- or ch,ch ; anything there
- jnz ratizd ; yes, branch
- and al,0f7h ; no, clear the bit
- ratizd: sub ch,cl ; above threshold?
- jna ratiz4 ; no, branch
- xor al,8 ; yes, set flag
- ratiz4: putn al ; send it out
- ratizz: nextv ; exit with video update
- ;==============================================================
- ; select intervals
- ; inputs:
- ; 0: sort step
- ; 1-4: inputs
- ;
- ; output: value at sorted step
- ;--------------------------------------------------------------
- public _sort
- _sort: getv al,var1 ; get the inputs
- getv ah,var2 ; /
- getv dl,var3 ; /
- getv dh,var4 ; /
- sort4 ; sort them
- mov word ptr temp0,ax ; put in temp array
- mov word ptr temp2,dx ; /
- getv bl,var0 ; get interval number
- and bx,3 ; mask
- add bx,offset dgroup:temp0 ; bx = table index
- mov al,[bx] ; get the value
- putn al ; send it out
- nextv ; exit
- ;==============================================================
- ; delta test
- ; inputs:
- ; 0: nz = hold
- ; 1: delta
- ; 2: nz = normalize within octave
- ; 3: input
- ; 4x: last input
- ; output: strobe when delta is detected
- ;--------------------------------------------------------------
- public _deltat
- _deltat:
- hold var0 ; hold?
- jnz deltatz ; exit if hold
- testv var1,-1 ; delta 0?
- jz deltatz ; yes, just exit
- ;
- getv al,var3 ; get pitch input for delta
- mov ah,al ; setup
- testv var2,-1 ; want to normalize
- jz deltat1 ; no, branch
- normal ; normalize
- deltat1:getv al,var1 ; get delta
- xchg ah,var4[di] ; swap input with last one
- sub ah,var4[di] ; delta match?
- cmp ah,al ; /
- jz deltat2 ; yes, branch
- neg al ; else swap sign
- cmp ah,al ; try again
- jz deltat2 ; branch if = delta
- jmp deltatz ; no, exit
- ;
- deltat2:mov byte ptr outn[di],1; set flag
- deltatz:nextt ; strobe
- ;==============================================================
- ; * 12, + offset
- ; inputs:
- ; 0: value
- ; 1: offset
- ;
- ; output: value * 12 + offset
- ;--------------------------------------------------------------
- public _mul12
- _mul12:
- getv al,var0 ; get value
- mov dl,12 ; for octave
- mul dl ; * 12
- getv ah,var1 ; get offset
- add al,ah ; add it in
- putn al ; send it out
- nextv ; exit
- ;==============================================================
- ; / 12
- ; input: 0: value
- ; output: value / 12
- ;--------------------------------------------------------------
- public _div12
- _div12:
- getv al,var0 ; get value
- or al,al ; zero not allowed
- jz div12x ; split if zero
- mov dl,12 ; for octave
- mov ah,0 ; make into word
- div dl ; / 12
- div12x: putn al ; send it out
- nextv ; exit
- ;==============================================================
- ; mod 12
- ; input: 0: value
- ; 1: offset
- ; output: value mod 12
- ;--------------------------------------------------------------
- public _mod12
- _mod12:
- getv al,var0 ; get value
- mov ah,0 ; load for 0
- or al,al ; zero not allowed
- jz mod12x ; split if zero
- mov dl,12 ; for octave
- div dl ; / 12
- mod12x: getv al,var1 ; get offset
- add al,ah ; add in mod value
- putn al ; send it out
- nextv ; exit
- ;==============================================================
- ; fold to octave range
- ; input: 0: value
- ; 1: octave range
- ; 2: offset
- ; output: value mod 12
- ;--------------------------------------------------------------
- public _fold
- _fold:
- getv al,var1 ; get max octave range
- and al,15 ; limit
- mov ch,12 ; octave
- mul ch ; /
- add ch,al ; ch = max
- ;
- getv ah,var0 ; get input
- range ah,ch ; put in range
- getv al,var2 ; get offset
- add al,ah ; add in mod value
- putn al ; send it out
- nextv ; exit
- ;==============================================================
- ; Union
- ; inputs: 0: trigger, 1: sync, 2x: clocks, 2z: trig flag
- ; output: pulse of one loop cycle duration
- ;--------------------------------------------------------------
- public _union
- _union:
- tick var0,var2 ; clock trig input
- jnc union0 ; branch if no tick
- mov byte ptr var2+1[di],1 ; else set holding byte
- union0: tickb1 var1,var2 ; clock sync input
- jnc unionz ; branch if no tick
- mov al,0 ; else clear trigger, if any
- xchg al,var2+1[di] ; get trigger, if any
- putn al ; send it out
- unionz: nextt ; strobe
-
- ;==============================================================
- ; Flip-flop
- ; inputs: 0: set, 1: reset, 2x: set-tick, 2z: reset-tick
- ; output: pulse of one loop cycle duration
- ;--------------------------------------------------------------
- public _fflop
- _fflop:
- tick var0,var2 ; clock tick
- jnc fflop1 ; branch if no set input
- mov byte ptr outn[di],1; set the pulse
- fflop1: tick var1,var2+1 ; clock tick
- jnc fflop2 ; branch if no reset input
- mov byte ptr outn[di],0; reset the pulse
- fflop2: nextl ; exit with led update
- ;==============================================================
- ; shift left
- ; inputs: 0: value, 1: shift ammount, 2: mask
- ; output: shifted value
- ;--------------------------------------------------------------
- public _lshift
- _lshift:
- getv cl,var1 ; get the exponent
- and cl,07H ; 0-7 allowed
- getv al,var0 ; get the value
- rol al,cl ; shift
- getv ah,var2 ; get mask
- and al,ah ; mask output
- putn al ; send it out
- nextv ; exit with video update
- ;==============================================================
- ; shift right
- ; inputs: 0: value, 1: shift ammount, 2: mask
- ; output: shifted value
- ;--------------------------------------------------------------
- public _rshift
- _rshift:
- getv cl,var1 ; get the exponent
- and cl,07H ; 0-7 allowed
- getv al,var0 ; get the value
- ror al,cl ; shift
- getv ah,var2 ; get mask
- and al,ah ; mask output
- putn al ; send it out
- nextv ; exit with video update
- ;==============================================================
- ; Low Pass Filter
- ; inputs: 0: clock, 1: value, 2: slope, 3: offset
- ; 4x: index, 4z: clock tick, 5-12: storage
- ; output: average of last 2, 4, 8, or 16 inputs (slope 0-3)
- ;--------------------------------------------------------------
- public _filter
- _filter:
- tick var0,var4+1 ; clock tick
- jc filte1 ; branch if there is a tick
- nextx ; else easy exit
- ;
- filte1: getv al,var1 ; get the input value
- getv cl,var2 ; get the slope
- and cl,03H ; 0-3 allowed
- mov dl,2 ; shift
- shl dl,cl ; dl = 2, 4, 8, or 16
- mov dh,dl ; copy
- dec dh ; dh = 1, 3, 7, or 15
- mov bl,var4[di] ; get index
- inc bl ; bump it
- and bl,dh ; keep in bounds
- mov var4[di],bl ; put it away
- mov bh,0 ; bx = index offset
- mov var5[bx+di],al ; put value into save list
- mov dh,cl ; dh = slope value (for later)
- mov cl,dl ; get slope count
- mov ch,0 ; cx = 2, 4, 8, or 16
- mov bx,var5 ; bx = start of save table
- mov bp,0 ; bp will get sum of saved inputs
- mov ah,0 ; ax will get each byte saved
- filte2: mov al,[bx+di] ; get the saved byte
- add bp,ax ; sum of saved bytes
- inc bx ; /
- loop filte2 ; /
- mov ax,bp ; ax = sum of saved byte values
- mov cl,dh ; dh = slope value
- inc cl ; bump
- shr ax,cl ; ax = average of saved inputs
- getv ah,var3 ; get offset
- add al,ah ; add to averaged value
- putn al ; send it out
- nextv ; exit with video update
- ;==============================================================
- ; Power of 2
- ; inputs: 0: value
- ; output: 2 ^^ value
- ;--------------------------------------------------------------
- public _twopwr
- _twopwr:
- getv cl,var0 ; get the exponent
- and cl,07H ; 0-7 allowed
- mov al,1 ; shift
- shl al,cl ; /
- putn al ; send it out
- nextv ; exit with video update
- ;==============================================================
- ; Test for flagged bits
- ; inputs: 0: input, 1: value
- ; output: 1 if any masked bits are hi, else 0
- ;--------------------------------------------------------------
- public _bitsp
- _bitsp: getv al,var0 ; get input
- mov dl,0 ; flag = false
- test al,-1 ; any bits hi?
- jz bitsp1 ; no, branch
- getv dl,var1 ; yes, get the value
- bitsp1: putn dl ; send the flag
- nextl ; exit with led update
- ;==============================================================
- ; Test for flagged bits
- ; inputs: 0: input, 1: bitmask, 2: value
- ; output: 1 if any masked bits are hi, else 0
- ;--------------------------------------------------------------
- public _bitsq
- _bitsq: getv al,var0 ; get input
- getv ah,var1 ; get mask byte
- mov dl,0 ; flag = false
- test al,ah ; any bits hi?
- jz bitsq1 ; no, branch
- getv dl,var2 ; yes, get the value
- bitsq1: putn dl ; send the flag
- nextl ; exit with led update
- ;==============================================================
- ; Test for minus ( bit 7 high)
- ; inputs: 0: input
- ; output: 1 if bit 7 hi, else 0
- ;--------------------------------------------------------------
- public _minusp
- _minusp:
- getv al,var0 ; get input
- mov dl,0 ; flag = false
- test al,80H ; is negative?
- jz minusp1 ; no, branch
- inc dl ; yes, flag = true
- minusp1:putn dl ; send the flag
- nextl ; exit with led update
- ;==============================================================
- ; Test for non-zero
- ; inputs: 0: input
- ; output: 0 if input is 0, else 1
- ;--------------------------------------------------------------
- public _truep
- _truep:
- getv al,var0 ; get input
- mov dl,1 ; flag = false
- or al,al ; is zero?
- jnz truep1 ; no, branch
- dec dl ; yes, flag = true
- truep1: putn dl ; send the flag
- nextl ; exit with led update
- ;==============================================================
- ; Test for zero
- ; inputs: 0: input
- ; output: 1 if input is 0, else 0
- ;--------------------------------------------------------------
- public _zerop
- _zerop:
- getv al,var0 ; get input
- mov dl,0 ; flag = false
- or al,al ; is zero?
- jnz zerop1 ; no, branch
- inc dl ; yes, flag = true
- zerop1: putn dl ; send the flag
- nextl ; exit with led update
- ;==============================================================
- ; Test for within range
- ; inputs: 0: input, 1: hi bounds, 2: low bounds
- ; output: 1 if within range, else 0
- ;--------------------------------------------------------------
- public _rangep
- _rangep:
- getv al,var0 ; get input
- mov dl,0 ; flag = false
- getv ah,var1 ; get hi range
- cmp al,ah ; input > hi range?
- ja range1 ; yes, exit False
- getv ah,var2 ; get lo range
- cmp al,ah ; input < lo range?
- jb range1 ; yes, exit False
- inc dl ; no, flag = True
- range1: putn dl ; send the flag
- nextl ; exit with led update
- ;==============================================================
- ; Test for a > b
- ; inputs: 0: input a, 1: input b
- ; output: 1 if a > b, else 0
- ;--------------------------------------------------------------
- public _great
- _great:
- getv al,var0 ; get input a
- getv ah,var1 ; get inmpu b
- mov dl,0 ; flag = false
- cmp al,ah ; is a > b ?
- jna great1 ; no, branch
- inc dl ; yes, flag = true
- great1: putn dl ; send the flag
- nextl ; exit with led update
- ;==============================================================
- ; Test for a < b
- ; inputs: 0: input a, 1: input b
- ; output: 1 if a < b, else 0
- ;--------------------------------------------------------------
- public _lessp
- _lessp:
- getv al,var0 ; get input a
- getv ah,var1 ; get inmpu b
- mov dl,0 ; flag = false
- cmp al,ah ; is a < b ?
- jnb lessp1 ; no, branch
- inc dl ; yes, flag = true
- lessp1: putn dl ; send the flag
- nextl ; exit with led update
- ;==============================================================
- ; Test for change
- ; inputs: 0: input, 1x: last input value
- ; output: 1 if change else 0
- ;--------------------------------------------------------------
- public _change
- _change:
- mov ah,0 ; clear flag
- getv al,var0 ; get input 1
- cmp al,var1[di] ; same as last?
- jz chang1 ; yes, send "no change"
- inc ah ; else send change
- chang1: putn ah ; send the flag
- mov var1[di],al ; save value for next time
- nextl ; exit with led update
- ;==============================================================
- ; Test for equal
- ; inputs: 0: input, 1: input
- ; output: 1 if equal, else 0
- ;--------------------------------------------------------------
- public _equal
- _equal:
- getv al,var0 ; get input 1
- getv ah,var1 ; get inmpu 2
- mov dl,0 ; flag = false
- cmp al,ah ; are they equal
- jnz equal1 ; no, branch
- inc dl ; yes, flag = true
- equal1: putn dl ; send the flag
- nextl ; exit with led update
- ;==============================================================
- ; Test for not equal
- ; inputs: 0: input, 1: input
- ; output: 1 if not equal, else 0
- ;--------------------------------------------------------------
- public _nequal
- _nequal:
- getv al,var0 ; get input 1
- getv ah,var1 ; get inmpu 2
- mov dl,0 ; flag = false
- cmp al,ah ; are they equal
- jz nequal1 ; yes, branch
- inc dl ; no, flag = true
- nequal1:putn dl ; send the flag
- nextl ; exit with led update
- ;==============================================================
- ; output: delayed input
- ; input: 0: value
- ; 1: delay clocks
- ; 2: offset
- ; 3: index
- ; 4-131: value array
- ;--------------------------------------------------------------
- public _delay
- _delay: getv al,var0 ; get input value
- getv dl,var1 ; get number of clocks delay
- getv dh,var2 ; get offset
- mov bl,var3[di] ; get current count
- dec byte ptr var3[di]; bump it
- mov bh,0 ; byte --> word
- mov var4[bx+di],al ; set input byte
- add bl,dl ; add delay
- mov al,var4[bx+di] ; get the output byte
- add al,dh ; add offset
- putn al ; send the new output
- nextv
- ;==============================================================
- ; output: the last changed input
- ; input: 0-7: values
- ; 8x - 9+: saved values
- ;--------------------------------------------------------------
- public _lastv
- _lastv: mov bp,si ; save si
- mov dx,di ; save di
- mov si,di ; set si to saved values
- add si,var8 ; /
- add di,var0 ; set di to input values
- mov cx,8 ; 8 to do
- lastvl: mov bx,[di] ; point to var addr
- mov al,[bx] ; get it
- cmp al,[si] ; same?
- jnz lastvx ; yes, exit
- add di,2 ; point to next
- inc si ; /
- loop lastvl ; do all 8
- mov di,dx ; restore registers
- mov si,bp ; /
- nextx ; easy exit if no change
- ;
- lastvx: mov [si],al ; set the flag
- mov di,dx ; restore registers
- mov si,bp ; /
- putn al ; send the new output
- nextv
- ;==============================================================
- ; Quantize value input to nearest match input
- ; inputs: 0: value input, 1: extract value, 2-9: match inputs
- ; output: nearest match input
- ;--------------------------------------------------------------
- public _quant
- _quant:
- getv dl,var0 ; dl = value input
- ;
- getv cl,var1 ; get extract root
- or cl,cl ; if zero, ignore
- jz quant0 ; /
- ;
- mov al,dl ; get the value
- or al,al ; zero not allowed
- jz quant0a ; split if zero
- mov ah,0 ; make into word
- div cl ; divide by extract value
- mov dl,ah ; mod result is compare value
- mul cl ; restore to base
- quant0a:mov cl,al ; cl is base
- ;
- quant0: mov dh,-1 ; dh = initialized test
- ;
- getv al,var2 ; get match input
- mov ah,dl ; get value input
- sub ah,al ; get difference
- cmp ah,dh ; difference < test
- jnb quant1a ; no, branch
- mov dh,ah ; yes, difference is new test
- putn al ; match input --> output
- quant1a:neg ah ; test abs difference
- cmp ah,dh ; abs difference < test
- jnb quant2 ; no, branch
- mov dh,ah ; yes, difference is new test
- putn al ; match input --> output
- ;
- quant2: getv al,var3 ; get match input
- mov ah,dl ; get value input
- sub ah,al ; get difference
- cmp ah,dh ; difference < test
- jnb quant2a ; no, branch
- mov dh,ah ; yes, difference is new test
- putn al ; match input --> output
- quant2a:neg ah ; test abs difference
- cmp ah,dh ; abs difference < test
- jnb quant3 ; no, branch
- mov dh,ah ; yes, difference is new test
- putn al ; match input --> output
- ;
- quant3: getv al,var4 ; get match input
- mov ah,dl ; get value input
- sub ah,al ; get difference
- cmp ah,dh ; difference < test
- jnb quant3a ; no, branch
- mov dh,ah ; yes, difference is new test
- putn al ; match input --> output
- quant3a:neg ah ; test abs difference
- cmp ah,dh ; abs difference < test
- jnb quant4 ; no, branch
- mov dh,ah ; yes, difference is new test
- putn al ; match input --> output
- ;
- quant4: getv al,var5 ; get match input
- mov ah,dl ; get value input
- sub ah,al ; get difference
- cmp ah,dh ; difference < test
- jnb quant4a ; no, branch
- mov dh,ah ; yes, difference is new test
- putn al ; match input --> output
- quant4a:neg ah ; test abs difference
- cmp ah,dh ; abs difference < test
- jnb quant5 ; no, branch
- mov dh,ah ; yes, difference is new test
- putn al ; match input --> output
- ;
- quant5: getv al,var6 ; get match input
- mov ah,dl ; get value input
- sub ah,al ; get difference
- cmp ah,dh ; difference < test
- jnb quant5a ; no, branch
- mov dh,ah ; yes, difference is new test
- putn al ; match input --> output
- quant5a:neg ah ; test abs difference
- cmp ah,dh ; abs difference < test
- jnb quant6 ; no, branch
- mov dh,ah ; yes, difference is new test
- putn al ; match input --> output
- ;
- quant6: getv al,var7 ; get match input
- mov ah,dl ; get value input
- sub ah,al ; get difference
- cmp ah,dh ; difference < test
- jnb quant6a ; no, branch
- mov dh,ah ; yes, difference is new test
- putn al ; match input --> output
- quant6a:neg ah ; test abs difference
- cmp ah,dh ; abs difference < test
- jnb quant7 ; no, branch
- mov dh,ah ; yes, difference is new test
- putn al ; match input --> output
- ;
- quant7: getv al,var8 ; get match input
- mov ah,dl ; get value input
- sub ah,al ; get difference
- cmp ah,dh ; difference < test
- jnb quant7a ; no, branch
- mov dh,ah ; yes, difference is new test
- putn al ; match input --> output
- quant7a:neg ah ; test abs difference
- cmp ah,dh ; abs difference < test
- jnb quant8 ; no, branch
- mov dh,ah ; yes, difference is new test
- putn al ; match input --> output
- ;
- quant8: getv al,var9 ; get match input
- mov ah,dl ; get value input
- sub ah,al ; get difference
- cmp ah,dh ; difference < test
- jnb quant8a ; no, branch
- mov dh,ah ; yes, difference is new test
- putn al ; match input --> output
- quant8a:neg ah ; test abs difference
- cmp ah,dh ; abs difference < test
- jnb quant9 ; no, branch
- mov dh,ah ; yes, difference is new test
- putn al ; match input --> output
- ;
- quant9: add outn[di],cl ; add base
- nextv ; exit with video update
- ;==============================================================
- ; Keep the highest input
- ; inputs: 0: hold/reset 1: input
- ; output: highest input since reset
- ;--------------------------------------------------------------
- public _higher
- _higher:
- hold var0 ; hold?
- jz higher0 ; branch if no hold
- getv al,var1 ; else get the input
- putn al ; send it to the output
- nextv ; exit
- higher0:getv al,var1 ; get the value
- cmp al,outn[di] ; higher than already there?
- jna higher1 ; no, branch
- putn al ; yes, send the new value
- higher1:nextv ; exit with video update
- ;==============================================================
- ; Keep the lowest input
- ; inputs: 0: hold/reset 1: input
- ; output: lowest input since reset
- ;--------------------------------------------------------------
- public _lower
- _lower:
- hold var0 ; hold?
- jz lower0 ; branch if no hold
- getv al,var1 ; else get the input
- putn al ; send it to the output
- nextv ; exit
- lower0: getv al,var1 ; get the value
- cmp al,outn[di] ; lower than already there?
- jnb lower1 ; no, branch
- putn al ; yes, send the new value
- lower1: nextv ; exit with video update
- ;==============================================================
- ; Keep input between limits
- ; inputs: 0: input, 1: upper bounds, 2: lower bounds
- ; output: input between bounds
- ;--------------------------------------------------------------
- public _limit
- _limit:
- getv al,var0 ; get the value
- getv ah,var1 ; get upper limit
- cmp al,ah ; less than upper limit?
- jna limit1 ; yes, branch
- mov al,ah ; else set it to upper limit
- limit1: getv ah,var2 ; get lower limit
- cmp al,ah ; greater than lower limit?
- jnb limit2 ; yes, branch
- mov al,ah ; else set it to lower limit
- limit2: putn al ; send the value
- nextv ; exit w video
- ;==============================================================
- ; Sample & Hold
- ; inputs: 0: follow 1: clock, 2: read 3: offset 4x: clock tick
- ; output: scaled sample
- ;--------------------------------------------------------------
- public _sandh
- _sandh:
- testv var0,-1 ; follow on?
- jnz sandh1 ; yes, branch
- tick var1,var4 ; clock tick
- jc sandh1 ; branch if there is a tick
- nextx ; else exit easy
- sandh1: getv al,var2 ; get sample
- getv ah,var3 ; get offset
- add al,ah ; put it together
- putn al ; send it
- nextv ; exit with video update
- ;==============================================================
- ; Midi sync control interface for Stop, Start, Continue, etc.
- ; output: bit flags
- ; bit 0: stop
- ; bit 1: start
- ; bit 2: continue
- ; input:
- ; 0: NZ = send Stop to Midi
- ; 1: NZ = send Start to MIDI
- ; 2: NZ = send Continue to MIDI
- ; 3: NZ = send Reset to MIDI
- ; 4: NZ = send Tune req to midi
- ; 5: NZ bits = clear output bits
- ; 6x: last stop input
- ; 6+: last start input
- ; 7x: last continue input
- ; 7+: initialized flag
- ; 8x: tick for stop, start, continue
- ; 8+: tick for reset, tune, clear
- ;--------------------------------------------------------------
- public _stopo
- _stopo: cmp byte ptr var7+1[di],0abh; initialized?
- jz stopo0 ; yes, branch
- mov word ptr var7[di],0ab00h; no, initialize
- mov word ptr var8[di],0 ; /
- mov word ptr var6[di],0 ; /
- jmp stopox ; exit from init
- ;
- stopo0: mov al,cs:mstop ; change in ext stop?
- cmp al,var6[di] ; /
- jz stopo0a ; no, branch
- or byte ptr outn[di],1 ; yes, set the flag
- mov var6[di],al ; /
- ;
- stopo0a:mov al,cs:mstart ; change in ext start?
- cmp al,var6+1[di] ; /
- jz stopo0b ; no, branch
- or byte ptr outn[di],2 ; yes, set the flag
- mov var6+1[di],al ; /
- ;
- stopo0b:mov al,cs:mcont ; change in ext cont?
- cmp al,var7[di] ; /
- jz stopo1 ; no, branch
- or byte ptr outn[di],4 ; yes, set the flag
- mov var7[di],al ; /
- ;--------------------------------------------------------------
- stopo1: tick var0,var8 ; stop cmd input?
- jnc stopo1a ; no, branch
- mov al,0fch ; send Stop cmd to midi
- call allmidi
- ;
- stopo1a:tickb1 var1,var8 ; start cmd input?
- jnc stopo1b ; no, branch
- mov al,0fah ; send Start cmd to midi
- call allmidi
- ;
- stopo1b:tickb2 var2,var8 ; Cont cmd input?
- jnc stopo2 ; no, branch
- mov al,0fbh ; send Cont cmd to midi
- call allmidi
- ;--------------------------------------------------------------
- stopo2: tick var3,var8+1 ; Reset cmd input?
- jnc stopo2a ; no, branch
- mov al,0ffh ; send Reset cmd to midi
- call allmidi
- ;
- stopo2a:tickb1 var4,var8+1 ; Tune Request input?
- jnc stopo3 ; no, branch
- mov al,0f6h ; send Tune Request to midi
- call allmidi
- ;--------------------------------------------------------------
- stopo3: tickb2 var5,var8+1 ; clear output?
- jnc stopox ; no, branch
- mov byte ptr outn[di],0 ; clear the output
- stopox: nextl ; show it
- ;==============================================================
- ; Sum of 5 inputs
- ; inputs: 0-4: inputs, 5: scale 6: offset
- ; output: scaled and offset input
- ;--------------------------------------------------------------
- public _sumit
- _sumit:
- xor cx,cx ; clr cx
- mov ah,ch ; clr ah
- getv al,var0 ; get input
- add cx,ax ; add to total
- getv al,var1 ; get input
- add cx,ax ; add to total
- getv al,var2 ; get input
- add cx,ax ; add to total
- getv al,var3 ; get input
- add cx,ax ; add to total
- getv al,var4 ; get input
- add cx,ax ; add to total
- ;
- getv al,var5 ; get scale value
- xchg al,ah ; al = 0, ah = scale
- mul cx ; dx = scaled value
- getv al,var6 ; get offset
- add al,dl ; put it together
- putn al ; send it
- nextv ; exit with video update
- ;==============================================================
- ; Mix 3 Scaled inputs
- ; inputs: 0,2,4: input, 1,3,5: scale 6: offset
- ; output: scaled and offset input
- ;--------------------------------------------------------------
- public _mixit
- _mixit:
- getv al,var0 ; get input
- getv cl,var1 ; get scale value
- mul cl ; ah = scaled value
- mov ch,ah ; for sum
- getv al,var2 ; get input
- getv cl,var3 ; get scale value
- mul cl ; ah = scaled value
- add ch,ah ; sum
- getv al,var4 ; get input
- getv cl,var5 ; get scale value
- mul cl ; ah = scaled value
- add ch,ah ; sum
- ;
- getv al,var6 ; get offset
- add al,ch ; put it together
- putn al ; send it
- nextv ; exit with video update
- ;==============================================================
- ; Scale and offset input
- ; inputs: 0: input, 1: scale 2: offset
- ; output: scaled and offset input
- ;--------------------------------------------------------------
- public _scale
- _scale:
- getv al,var0 ; get input
- getv cl,var1 ; get scale value
- mul cl ; ah = scaled value
- getv al,var2 ; get offset
- add al,ah ; put it together
- putn al ; send it
- nextv ; exit with video update
- ;==============================================================
- ; Max of two inputs
- ; inputs: 0: input, 1: input
- ; output: max
- ;--------------------------------------------------------------
- public _maxf
- _maxf:
- getv al,var0 ; get input
- getv ah,var1 ; get input
- cmp ah,al ; select larger
- jb maxf1 ; /
- mov al,ah ; /
- maxf1: putn al ; send it
- nextv ; exit with video update
- ;==============================================================
- ; Min of two inputs
- ; inputs: 0: input, 1: input
- ; output: min
- ;--------------------------------------------------------------
- public _minf
- _minf:
- getv al,var0 ; get input
- getv ah,var1 ; get input
- cmp al,ah ; select larger
- jb minf1 ; /
- mov al,ah ; /
- minf1: putn al ; send it
- nextv ; exit with video update
- ;==============================================================
- ; Rate of change (delta)
- ; inputs: 0: input, 1x: last input
- ; output: delta from last changed input
- ;
- public _delta
- _delta:
- getv al,var0 ; get input
- cmp al,byte ptr var1[di]; any change
- jnz delta1 ; yes, branch
- nextx ; no, easy exit
- ;
- delta1: mov ah,byte ptr var1[di]; get old value
- sub ah,al ; calc delta
- jnb delta2 ; keep it positive
- neg ah ; /
- delta2: mov byte ptr var1[di],al; save new input
- putn ah ; send delta
- nextv ; exit with video update
- ;==============================================================
- ; Add three inputs
- ; inputs: 0: input, 1: input, 2: input
- ; output: sum of the three inputs
- ;
- public _plus
- _plus:
- getv al,var0 ; get input
- getv ah,var1 ; get input
- add al,ah ; put it together
- getv ah,var2 ; get input
- add al,ah ; put it together
- putn al ; send it
- nextv ; exit with video update
- ;==============================================================
- ; Add two inputs, subtract the third
- ; inputs: 0: input, 1: input, 2: input
- ; output: sum of first two inputs minus the third
- ;
- public _plusm,_plusn
- _plusn: nop
- _plusm: getv al,var0 ; get input
- getv ah,var1 ; get input
- add al,ah ; put it together
- getv ah,var2 ; get input
- sub al,ah ; put it together
- putn al ; send it
- nextv ; exit with video update
- ;==============================================================
- ; multiply input by 2nd input, divide by 3rd if nz
- ; inputs: 0: input, 1: mult, 2: divid
- ; output: product of the 3 inputs
- ;
- public _times
- _times:
- getv al,var0 ; get input
- getv cl,var1 ; get input
- mul cl ; put it together
- getv cl,var2 ; get input
- or cl,cl ; zero?
- jz times1 ; yes, do not divide
- mov dx,0 ; give it headroom
- mov ch,0
- div cx ; divide dx:ax / cx
- times1: putn al ; send it
- nextv ; exit with video update
- ;==============================================================
- ; divide first input by 2nd, return remainder
- ; inputs: 0: input, 1: divide
- ; output: product of the 3 inputs
- ;
- public _modulo
- _modulo:
- getv al,var0 ; get input
- mov ah,0 ; setup for 0
- getv cl,var1 ; get input
- or cl,cl ; zero?
- jz modulx ; yes, do not divide
- div cl ; divide ax / cl
- modulx: putn ah ; send remainder
- nextv ; exit with video update
- ;==============================================================
- ; AND gate
- ; inputs: 0,1,2
- ; output: result of input0 AND input1 XOR input2
- ;--------------------------------------------------------------
- public _andl
- _andl:
- getv al,var0 ; al = 1st variable
- getv ah,var1 ; ah = 2nd variable
- and al,ah ; AND them
- getv ah,var2 ; ah = 3rd variable
- xor al,ah ; xor them
- putn al ; send to output
- nextv
- ;==============================================================
- ; AND gate
- ; inputs: 0: &input 1: &input 2: +input
- ; output: result of input 0 AND input 1 PLUS input 2
- ;--------------------------------------------------------------
- public _mask
- _mask:
- getv al,var0 ; al = 1st variable
- getv ah,var1 ; ah = 2nd variable
- and al,ah ; var0 AND var1
- getv ah,var2 ; ah = 3rd variable
- add al,ah ; add it to the AND stuff
- putn al ; send to output
- nextv
- ;==============================================================
- ; AND gate
- ; inputs: 0: &input 1: &input, 2: shift
- ; output: shifted result of input 0 AND input 1
- ;--------------------------------------------------------------
- public _maskl
- _maskl: getv al,var0 ; al = 1st variable
- getv ah,var1 ; ah = 2nd variable
- and al,ah ; var0 AND var1
- getv cl,var2 ; get shift
- rol al,cl ; shift
- putn al ; send to output
- nextv
- ;--------------------------------------------------------------
- public _maskr
- _maskr: getv al,var0 ; al = 1st variable
- getv ah,var1 ; ah = 2nd variable
- and al,ah ; var0 AND var1
- getv cl,var2 ; get shift
- ror al,cl ; shift
- putn al ; send to output
- nextv
- ;==============================================================
- ; NOT logic
- ; inputs: 0: value
- ; 1: mask
- ; output: NOT input0 AND input 1
- ;--------------------------------------------------------------
- public _notl
- _notl:
- getv al,var0 ; al = 1st variable
- not al ; complement
- getv ah,var1 ; get mask
- and al,ah ; AND them
- putn al ; send to output
- nextv
- ;==============================================================
- ; Slope detector
- ; inputs: 0
- ; output: nz if positive slope, z if neg, no change if 0
- ;
- ;--------------------------------------------------------------
- public _slope
- _slope:
- getv ah,var0 ; al = 1st variable
- cmp ah,var1[di] ; same as last?
- jz slopex ; yes, just exit
- mov var1[di],ah ; no, save it
- mov al,1 ; setup for pos
- ja slope1 ; branch if pos
- mov al,0 ; else flag neg
- slope1: putn al ; send to output
- slopex: nextl
-
- ;==============================================================
- ; negate
- ; inputs: 0: input
- ; output: NEG of input
- ;--------------------------------------------------------------
- public _negate
- _negate:
- getv al,var0 ; al = 1st variable
- neg al ; negate it
- putn al ; send to output
- nextv
- ;==============================================================
- ; OR gate
- ; inputs: 0,1,2
- ; output: result of input0 OR input1 OR input2
- ;--------------------------------------------------------------
- public _orl
- _orl:
- getv al,var0 ; var0 OR var1...
- getv ah,var1 ; /
- or al,ah ; /
- getv ah,var2 ; ...OR var2
- or al,ah ; /
- putn al ; send out
- nextv
- ;==============================================================
- ; shunt input to output
- ; inputs: 0: value
- ; output: input 0 unchanged
- ;--------------------------------------------------------------
- public _value
- _value:
- getv al,var0 ; get variable 1
- putn al ; send it
- nextv
- ;==============================================================
- ; display input value in ascii
- ; inputs: 0-2: values to be displayed
- ; outputs: none
- ;--------------------------------------------------------------
- public _ascii
- _ascii:
- getv al,var0 ; get the input value
- getv ah,var1 ; /
- getv cl,var2 ; /
- mov es,4[di] ; get seg addr
- mov bx,6[di] ; get module screen address
- mov es:318[bx],al ; put to the screen
- mov es:320[bx],ah ; /
- mov es:322[bx],cl ; /
- nextx ; exit
- ;==============================================================
- ; display input value in ascii from seq "s"
- ; inputs: 0: lo addr of value, 1: hi addr, 2: offset to addr
- ; outputs: none
- ;--------------------------------------------------------------
- public _ascis
- _ascis:
- mov ax,seg bufsp ; setup seg register
- mov es,ax ; es = seg addr
- getv dl,var0 ; get address
- getv dh,var1 ; get hi address
- and dh,15 ; 16 max
- getv bl,var2 ; get offset
- add dl,bl ; put them together
- mov bx,dx ; /
- mov al,es:[bx] ; get the byte
- inc bl ; bump addr low
- mov ah,es:[bx] ; and the next
- inc bl ; bump addr low
- mov cl,es:[bx] ; and the next
- ;
- mov es,4[di] ; get seg addr
- mov bx,6[di] ; get module screen address
- mov es:318[bx],al ; put to the screen
- mov es:320[bx],ah ; /
- mov es:322[bx],cl ; /
- nextx ; exit
- ;==============================================================
- ; display input value in ascii from seq "S"
- ; inputs: 0: lo addr of value, 1: hi addr, 2: offset
- ; outputs: none
- ;--------------------------------------------------------------
- public _asciz
- _asciz:
- mov ax,seg buffs ; setup seg register
- mov es,ax ; es = seg addr
- getv dl,var0 ; get address lo
- getv dh,var1 ; get address hi
- getv bl,var2 ; get offset
- mov bh,0 ; /
- add bx,dx ; set up as index
- mov al,es:[bx] ; get the byte
- mov ah,es:1[bx] ; and the next
- mov cl,es:2[bx] ; and the next
- ;
- mov es,4[di] ; get seg addr
- mov bx,6[di] ; get module screen address
- mov es:318[bx],al ; put to the screen
- mov es:320[bx],ah ; /
- mov es:322[bx],cl ; /
- nextx ; exit
- ;==============================================================
- ; display input value in decimal
- ; inputs: x: (display location)
- ; 0: value to be displayed
- ; outputs: copy of value
- ;--------------------------------------------------------------
- public _decin
- _decin:
- getv al,var0 ; get the input value
- putn al ; send to output
- mov colr,yellow ; set color to yellow
- mov es,4[di] ; get seg addr
- mov bx,6[di] ; get module screen address
- add bx,478 ; point to readout
- call todec ; do it
- mov colr,green ; fix it back to green
- nextv ; exit with update
- ;==============================================================
- ; display input value in decimal
- ; inputs: 0: decimal display
- ; outputs: none (display location)
- ;--------------------------------------------------------------
- public _decim
- _decim:
- mov colr,yellow ; set color to yellow
- getv al,var0 ; get the input value
- mov es,4[di] ; get seg addr
- mov bx,6[di] ; get module screen address
- add bx,318 ; point to readout
- call todec ; do it
- mov colr,green ; fix it back to green
- nextx ; exit, no update
- ;==============================================================
- ; slew over time
- ; formula:
- ; initialize:
- ; input * rate --> sum; input --> output
- ; thereafter until sum/rate = target:
- ; sum - input + target --> sum
- ; sum/rate --> output
- ;
- ; output: slewed input, with led hi while slewing
- ; inputs:
- ; 0: input
- ; 1: target
- ; 2: rate
- ; 3x: sum
- ; 4x: saved input
- ; 4+: saved target
- ; 5x: saved rate
- ; 5+: flag nz = busy
- ;--------------------------------------------------------------
- public _slew
- _slew: test byte ptr var5+1[di],1 ; busy?
- jnz slewa ; yes, branch
- getv dl,var1 ; no, see if target=output
- cmp dl,outn[di] ; /
- jnz slewb ; yes, go slew
- getv al,var0 ; no, see if input has changed
- cmp al,var4[di] ; /
- jz slewx ; yes, exit no change
- ;
- slewb: mov var4+1[di],dl ; save target
- getv al,var0 ; get input
- mov var4[di],al ; save input
- getv cl,var2 ; get rate
- mov var5[di],cl ; save rate
- ;
- putn dl ; target --> output
- or cl,cl ; rate = 0?
- jz slewx ; yes, just exit
- putn al ; no, start with input --> output
- mov byte ptr var5+1[di],1 ; flag busy
- mul cl ; ax = input * rate
- mov var3[di],ax ; set new sum
- jmp short slewx ; exit
- ;
- slewa: test byte ptr cs:loops,1 ; every other clock
- jnz slewx ; branch if not even
- mov ax,var3[di] ; ax = sum
- mov dl,var4[di] ; dx = input
- mov dh,0 ; /
- sub ax,dx ; ax = sum - input
- mov dl,var4+1[di] ; dx = target
- add ax,dx ; ax = sum - input + target
- mov var3[di],ax ; save new sum
- mov cl,var5[di] ; cl = rate
- div cl ; al = new sum / rate
- putn al ; send to output
- cmp al,dl ; output = target
- jnz slewx ; no, exit
- mov byte ptr var5+1[di],0 ; yes, flag not busy
- ;
- slewx: nextv ; exit
-
- ;==============================================================
- ; slew over time
- ; formula:
- ; initialize:
- ; input * 256 --> sum; input --> output
- ; thereafter until sum/256 = target:
- ; sum - input + target --> sum
- ; sum/256 --> output
- ;
- ; output: slewed input, with led hi while slewing
- ; inputs:
- ; 0: input
- ; 1: target
- ; 2: rate
- ; 3x: sum
- ; 4x: saved input
- ; 4+: saved target
- ; 5x: rate countdown
- ; 5+: flag nz = busy
- ;--------------------------------------------------------------
- public _xslew
- _xslew: test byte ptr var5+1[di],1 ; busy?
- jnz xslewa ; yes, branch
- getv dl,var1 ; no, see if target=output
- cmp dl,outn[di] ; /
- jnz xslewb ; yes, go slew
- getv al,var0 ; no, see if input has changed
- cmp al,var4[di] ; /
- jz xslewx ; yes, exit no change
- ;
- xslewb: mov var4+1[di],dl ; save target
- getv cl,var2 ; get rate
- mov var5[di],cl ; save rate
- getv al,var0 ; get input
- mov var4[di],al ; save input
- ;
- putn dl ; target --> output
- or cl,cl ; rate = 0?
- jz xslewx ; yes, just exit
- putn al ; no, start with input --> output
- mov byte ptr var5+1[di],1 ; flag busy
- mov ah,al ; ax = input * 256
- mov al,0 ; /
- mov var3[di],ax ; set new sum
- jmp short xslewx ; exit
- ;
- xslewa: dec byte ptr var5[di] ; countdown
- jnz xslewx ; /
- getv al,var2 ; get rate
- or al,al ; somebody make it 0?
- jnz xslewc ; no, go on
- getv al,var1 ; yes, set output to target
- mov dl,al ; ...short cut
- jmp short xslewz ; exit finished
- ;
- xslewc: mov var5[di],al ; save rate count
- mov ax,var3[di] ; ax = sum
- mov dl,var4[di] ; dx = input
- mov dh,0 ; /
- sub ax,dx ; ax = sum - input
- mov dl,var4+1[di] ; dx = target
- add ax,dx ; ax = sum - input + target
- mov var3[di],ax ; save new sum
- mov al,ah ; al = new sum / 256
- xslewz: putn al ; send to output
- cmp al,dl ; output = target
- jnz xslewx ; no, exit
- mov byte ptr var5+1[di],0 ; yes, flag not busy
- ;
- xslewx: nextv ; exit
-
- ;==============================================================
- ; display input value in scale of CM
- ; inputs: 0: value to be displayed
- ; outputs: none
- ;--------------------------------------------------------------
- public _noter
- _noter:
- mov colr,yellow ; set value color
- getv al,var0 ; get the input value
- mov es,4[di] ; get seg addr
- mov bx,6[di] ; get module screen address
- add bx,318 ; point to readout
- call tonote ; do it
- mov colr,green ; restore to green again
- nextx
- ;==============================================================
- _TEXT ENDS
- END
-
-