home *** CD-ROM | disk | FTP | other *** search
- TITLE Modules for Modular Sequencer
- NAME MBA
- .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
- ;==============================================================
- BUFPA SEGMENT
- if debug
- db 7fffh dup (?)
- db 7fffh dup (?)
- else
- db 7fffh dup (0)
- db 7fffh dup (0)
- endif
- BUFPA ENDS
- ;--------------------------------------------------------------
- BUFSP SEGMENT
- if debug
- db 4096 dup (?)
- else
- db 4096 dup (0)
- endif
- BUFSP ENDS
- ;--------------------------------------------------------------
- BUFFS SEGMENT
- if debug
- db 7fffh dup (?)
- db 7fffh dup (?)
- else
- db 7fffh dup (0)
- db 7fffh dup (0)
- endif
- BUFFS ENDS
- ;--------------------------------------------------------------
- BUFTU SEGMENT
- if debug
- db 4096 dup (?)
- else
- db 4096 dup (0)
- endif
- BUFTU ENDS
- ;==============================================================
- _DATA SEGMENT
- ASSUME DS:DGROUP, CS:_TEXT
- ;--------------------------------------------------------------
- extrn ticka:byte,tickis:byte,fastflg:byte
- extrn _header:byte
- extrn varsav:word,cmdflg:byte,special:word,cmdcnt:byte
- extrn locsav:word,cmdloc:word,vpage:word,curadr:word
- extrn midip:byte,valflg:byte,asensf:byte
- extrn @zero:near,magflg:byte,usrflg:byte,holdv:word
- extrn colr:byte,lodflg:byte
- extrn modnum:byte,doesc:word,clrchf:byte,curonf:byte
- ;--------------------------------------------------------------
- if debug
- extrn show0:word,show1:word,show2:word,show3:word
- endif
- ;--------------------------------------------------------------
- public midisf,midixsf,mpmodf,mpadrf,mpadr
- public mmcount,mmtick,mmreset,mmstart
- ;--------------------------------------------------------------
- midisf db 0 ; 0=no sync, 1=send sync
- midixsf db 0 ; 0=not xtrn sync, NZ=is
- mpmodf db 1 ; master program mode flag
- mpadrf db 0 ; nz if change in prog address
- mpadr db 0 ; master program address
- mmcount dw 0 ; master measure count
- mmtick dw 1 ; ticks left in current measure
- mmreset db 1 ; master measure reset flag
- mmstart db 1 ; master measurd start flag
- ;--------------------------------------------------------------
- public rseed,rhold,notetbl,notes
- public xcax,xcbx,xccx,xcdx
- public temp0,temp1,temp2,temp3
- ;--------------------------------------------------------------
- rseed dw 0 ; random number seed
- rhold db 0 ; nz = holding
- notes dw 4186,4435,4699,4978,5274,5588,5920,6272,6645,7040,7459,7902
- ;
- ;--------------------------------------------------------------
- ; notes --> clocks
- ;
- ; nv = 0 1 2 3 4 5 6 7
- ;
- notetbl db 192, 96, 48, 24, 12, 6, 3, 2 ; normal
- db 128, 64, 32, 16, 8, 4, 2, 2 ; dotted
- db 255,144, 72, 36, 18, 9, 5, 3 ; tripplett
- ;--------------------------------------------------------------
- ;
- xcax dw 0 ; register storage, used by xcall
- xcbx dw 0
- xccx dw 0
- xcdx dw 0
- ;
- temp0 db 0 ; temp storage, use within module
- temp1 db 0
- temp2 db 0
- temp3 db 0
- ;--------------------------------------------------------------
- ; the following are saved/loaded
- ;--------------------------------------------------------------
- public interv,mvlsav,mvlnum,mute,mutef,mprstf
- public mbeat,mnote,mtempo,mclocks
- public ctrlmap,pcva,pcvb,pcvc,pcvd,pcve,pcvf
- ;--------------------------------------------------------------
- mvlsav equ $ ; start of mod values to save
- interv db 64 dup(0) ; intervals for modulation
- ;
- mprstf db 0 ; master program reset flag
- mute dw -1 ; channel mute flags
- mutef db 1 ; 1=mute, 0=solo flag
- ;
- mbeat db 4 ; master beats/measure
- mnote db 24 ; master note value
- mtempo db 78H ; master tempo
- mclocks dw 96 ; master clocks/measure
- ;
- pcva db 16 dup (0) ; values sent to controller
- pcvb db 16 dup (0) ; values sent to controller
- pcvc db 16 dup (0) ; values sent to controller
- pcvd db 16 dup (0) ; values sent to controller
- pcve db 16 dup (0) ; values sent to controller
- pcvf db 16 dup (0) ; values sent to controller
- pcvg db 16 dup (0) ; values sent to controller
- pcvh db 16 dup (0) ; values sent to controller
- pcvx db 16 dup (0) ; values sent to controller
- pcvy db 16 dup (0) ; values sent to controller
- pcvz db 16 dup (0) ; values sent to controller
- ;
- ctrlmap db 7,1,2,3,4,5,64,65 ; midi controller map
- ctrlmpp db 7,1,2,3,4,5,64,65 ; midi controller map
- ;
- mvlnum equ $-mvlsav ; 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.
- slewe equ var22 ; programmer slew buffer
- slewf equ slewe+6 ; etc.
- slewg equ slewf+6 ; etc.
- slewh equ slewg+6 ; etc.
- pubuf equ slewh+6 ; programmer undo buffer
- psbuf equ pubuf+16 ; 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 midatix:byte,misend:byte
- extrn _cancel:near,workx:near,split:near
- extrn turnon:near,turnoff:near,noop:near,curon:near,curoff:near
- extrn mstart:byte,mstop:byte,mcont:byte,midata:byte,miflag:byte
- extrn sendm:near,alloff:near,tomidi:near,allmidi:near,allclr:near
- extrn tstmob:near,allclr:near,_mpuinf:byte,_mpuinm:byte
- ;==============================================================
- include macros.asm
- ;==============================================================
- ; THE MODULES
- ;==============================================================
-
- ;==============================================================
- ; Global Parameter Module
- ; (only one copy available)
- ; Output: Stop flag (is high for 1 cycle prior to HLT)
- ; Inputs:
- ; 0: NZ Sets master programmer reset flag
- ; 1: value --> master programmer address
- ; 2: NZ sets menu for solo, 0 sets mute
- ; 3: NZ sets Program-mode flag to Program, Z sets to Play
- ; 4: Beats Per measure, change recaluclates tick-count "ticka"
- ; 5: Note value for above, change recaluclates tick-count
- ; 6: Tempo, change reclalculates tick-count
- ; 7: Reset RNG. Any change sets seed to new value
- ; 8: bit 0 set MIDI output sync, bit 1 sets input sync
- ; 9: NZ transition causes HLT, if FF then BYE
- ; 10 : initialized flag
- ; 10+:
- ; 11 : Copy of ticks remaining
- ; 11+: Transition (tick) flags
- ;--------------------------------------------------------------
- public _alpha
- _alpha: cmp byte ptr var10[di],0ABh ; initialized yet?
- jz alphaz ; yes, go on
- mov byte ptr var10[di],0ABh ; no, set init values
- initv var3,1 ; prog <-- 1
- initv var4,4 ; beats <-- 4
- initv var5,3 ; note <-- 3
- initv var6,78h ; tempo <-- 78h
- alphaz:
- ;--------------------------------------------------------------
- ; 0: NZ Sets master programmer reset flag, Z releases
- ;
- mov al,mprstf ; get master reset flag
- and al,0FEH ; clear alpha reset bit
- testv var0,-1 ; check for Z/NZ
- jz alpha0a ; branch if Z
- or al,1 ; ...if NZ
- mov mmcount,0 ; clear measure count
- mov cs:seconds,0 ; reset clock
- mov cs:secondf,2 ; flag to show it
- mov mmtick,1 ; reset to 1st note in measure
- alpha0a:mov mprstf,al ; set/reset the flag
- ;--------------------------------------------------------------
- ; 1: value --> master programmer address
- ;
- getv al,var1 ; get the value
- cmp al,mpadr ; any change
- mov ah,0 ; setup to clear change flag
- jz alpha1a ; no, branch
- mov ah,1 ; yes, set change flag
- mov mpadr,al ; set new address
- alpha1a:mov mpadrf,ah ; flag change/no change
- ;--------------------------------------------------------------
- ; 2: NZ sets menu for solo, 0 sets mute
- ;
- mov al,1 ; set for mute
- testv var2,-1 ; get the flag
- jz alpha2a ; branch if solo
- mov al,0 ; else set for solo
- alpha2a:mov mutef,al ; set it
- ;--------------------------------------------------------------
- ; 3: NZ sets Program-mode flag to Program, Z sets to Play
- ;
- testv var3,-1 ; check for Z/NZ
- mov al,0 ; ...if Z
- jz alpha3a ; branch if Z
- inc al ; ...if NZ
- alpha3a:mov mpmodf,al ; set/reset the flag
- ;--------------------------------------------------------------
- ; 4: Beats Per measure, change recaluclates
- ;
- getv al,var4 ; get beats per measure
- cmp mbeat,al ; compare with master beats/measure
- jz alpha4z ; boogie if no change
- or al,al ; don't allow 0 either
- jz alpha4z ; /
- mov mbeat,al ; else set new beats/measure
- mov ah,mnote ; get clocks per note
- mul ah ; ax = clocks/measure
- mov mclocks,ax ; put away
- alpha4z:
- ;--------------------------------------------------------------
- ; 5: Note value for above, change recaluclates
- ;
- getv bl,var5 ; get note value
- cmp mnote,bl ; compare with master note value
- jz alpha5z ; boogie if no change
- cmp bl,5 ; 0-5 allowed
- ja alpha5z ; do nothing if > 6
- mov bh,0 ; else xlate to clocks
- add bx,offset dgroup:notetbl; /
- mov al,[bx] ; al = clocks
- mov mnote,al ; set new clocks/note
- mov ah,mbeat ; get beats/measure
- mul ah ; ax = clocks/measure
- mov mclocks,ax ; put away
- alpha5z:
- ;--------------------------------------------------------------
- ; 6: Tempo, change reclalculates tick-count
- ;
- getv dl,var6 ; get beats per measure
- mov fastflg,0 ; clear fast flag
- cmp dl,0ffh ; fast as possible?
- jnz alpha6b ; no, branch
- mov fastflg,1 ; yes, set flag
- alpha6b:cmp mtempo,dl ; compare with master tempo
- jz alpha6z ; boogie if no change
- mov mtempo,dl ; else set new value
- cmp dl,5 ; must be > 5
- ja alpha6a ; branch if ok
- mov dl,6 ; else make it 6
- alpha6a:mov ax,1456 ; calculate loop ticks
- div dl ; /
- mov ticka,al ; put it in the timer
- alpha6z:
- ;--------------------------------------------------------------
- ; 7: Reset RNG. Any change sets seed to new value
- ;
- getv al,var7 ; get rng seed
- or al,al ; is zero?
- jz alpha7z ; yes, don't set new seed
- ror al,1 ; 1 --> 80H, etc.
- mov ah,al ; 255 possible seeds
- mov rseed,ax ; set the new seed
- alpha7z:mov rhold,al ; set/clear hold flag
- ;--------------------------------------------------------------
- ; 8: bit 0 sets output sync, bit 1 sets input sync
- ;
- test valflg,-1 ; inputting values now?
- jnz alpha8d ; yes, don't do nothin
- getv dl,var8 ; get the flag
- mov ax,0 ; clear sync flags
- test dl,1 ; output sync?
- jz alpha8a ; no, branch
- mov al,1 ; yes, set out sync flag
- alpha8a:test dl,2 ; input sync?
- jz alpha8b ; no, branch
- mov ah,1 ; yes, set input sync flag
- alpha8b:mov midisf,al ; set sync out flag
- mov midixsf,ah ; set external sync flag
- test dl,6 ; defeat active sensing?
- mov al,1 ; ...setup for no defeat
- jz alpha8c ; no, branch
- mov al,0 ; yes, clear active sensing flag
- alpha8c:mov asensf,al ; set the flag
- alpha8d:
- ;--------------------------------------------------------------
- ; 9: NZ transition causes HLT.
- ; Value of FF causes BYE.
- ;
- tick var9,var11+1 ; clock tick
- jc alpha9c ; /
- jmp alpha9z ; boogie if no tick
- alpha9c:
- getv al,var9 ; check for FF (split)
- cmp al,0ffh ; wanna split?
- jz alpha9e ; yes, do it
- jmp alpha9a ; no, branch to HLT
- alpha9e:
- call alloff ; process all notes off
- jmp split ; become history
- alpha9a: ; HLT
- mov bx,6E0H ; menu text offset
- call turnon ; turn on the menu text
- or mprstf,2 ; set HLT flag
- mov al,0fch ; send MIDI STOP command
- call allmidi ; /
- alpha9z:
- ;--------------------------------------------------------------
- ; display number of calculation clocks available
- ;
- alpha11:mov al,tickis ; get ticks remaining
- cmp al,var11[di] ; same as before?
- jz alpha11z ; yes, boogie
- mov var11[di],al ; no, save new value
- gettag ; es:bx = screen addr of tag
- or al,al ; test for bottoming out
- jz alpha11a ; branch if Z
- and byte ptr es:(160*13-1)[bx],0F7H; lowlight if NZ
- jmp short alpha11b ; then branch around highlight
- alpha11a:or byte ptr es:(160*13-1)[bx],8; highlight if Z
- alpha11b:tohex ; convert to hex word
- mov es:(160*13)[bx],ah; put to the screen
- mov es:(160*13+2)[bx],al; /
- alpha11z:
- ;--------------------------------------------------------------
- ; shunt stop flag to output
- ;
- alphax: mov al,mprstf ; get the flag
- shr al,1 ; HLT is bit 2
- putn al ; send it out
- nextl ; show it
-
- ;==============================================================
- ; absolute time counter
- ; output: ticks count AND input0
- ; input: 0: hold, 1: period, 2: AND mask
- ;
- ;--------------------------------------------------------------
- public _beta
- _beta: hold var0 ; hold?
- jz beta0 ; no, branch
- mov al,0 ; yes, clear clock
- jmp short betax ; exit
- ;
- beta0: mov ax,cs:ticks ; get timer value
- getv cl,var1 ; get period
- shr ax,cl ; bump
- getv ah,var2 ; get AND mask
- and al,ah ; AND them
- betax: putn al ; send to output
- nextl
- ;==============================================================
- ; seconds counter
- ; output: seconds count AND input0
- ; input: 0: hold/reset
- ; 1: nz = minutes
- ; 2: offset
- ;
- ;--------------------------------------------------------------
- public _secs
- _secs: hold var0 ; hold?
- jz secs0 ; no, branch
- mov ax,cs:seconds ; yes, get current second count
- mov var2[di],ax ; set new time offset
- jmp short secsz ; exit
- ;
- secs0: mov ax,cs:seconds ; get timer value
- sub ax,var2[di] ; subtract offset
- mov dx,0 ; double word
- getv ch,var1 ; get clock flag
- test ch,-1 ; leave free count?
- jz secsx ; yes, branch
- mov bx,60 ; no,/60
- div bx ; /
- cmp ch,1 ; want seconds?
- jnz secsx ; no, do minutes
- mov al,dl ; yes, mod for secs
- secsx: 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
- ;
- cmp ch,1 ; want seconds?
- jnz secsz ; no, branch
- mov byte ptr es:[bx],':'; yes, print ':'
- secsz: nextv
- ;==============================================================
- ; simple loop counter
- ; output: loop count AND input0
- ; input: 0: hold, 1: period, 2: AND mask
- ;
- ;--------------------------------------------------------------
- public _lambda
- _lambda:hold var0 ; hold?
- jz lambda0 ; no, branch
- mov al,0 ; yes, clear clock
- jmp short lambdax ; exit
- ;
- lambda0:mov ax,cs:loops ; get count
- getv cl,var1 ; get period
- shr ax,cl ; bump
- getv ah,var2 ; get AND mask
- and al,ah ; AND them
- lambdax:putn al ; send to output
- nextl
- ;==============================================================
- ; measure clock
- ; output: measure start strobe, with delay
- ; input:
- ; 0: Hold
- ; 1: delay value
- ; 2x: countdown
- ; 2z: trip flag
- ;--------------------------------------------------------------
- public _mclk
- _mclk: mov byte ptr outn[di],0; clear output
- hold var0 ; hold?
- jnz mclkx ; yes, exit
- ;
- mov al,var2+1[di] ; trip flag on?
- or al,mmstart ; or measure start?
- jz mclkx ; no, exit
- ;
- test byte ptr var2+1[di],1; trip flag?
- jnz mclk0 ; yes, go countdown
- getv al,var1 ; no, get delay value
- inc al ; 0 --> 1
- mov var2[di],al ; set new countdown
- mov byte ptr var2+1[di],1; set trip flag
- ;
- mclk0: dec byte ptr var2[di] ; count down
- jnz mclkx ; exit if not end of count
- mov byte ptr var2+1[di],0; else clear trip flag
- mov byte ptr outn[di],1 ; set output
- ;
- mclkx: nextl ; exit
- ;==============================================================
- ; measure clock
- ; output: clock strobe
- ; input: 0: reset, 1: count, 2x:countdown timer, 2z: copy of count
- ;
- ;--------------------------------------------------------------
- public _mclock
- _mclock:hold var0 ; hold?
- jz mclock2 ; no, branch
- getv al,var1 ; yes, reset
- mov ah,al ; /
- mov var2[di],ax ; /
- jmp short mclockz ; exit with output=0
- ;
- mclock2:test mmstart,1 ; measure start?
- jz mclockz ; no, exit
- mov ah,1 ; yes, set output=1
- ;
- getv al,var1 ; get current count
- cmp al,var2+1[di] ; same as before?
- jz mclock1 ; yes, branch
- mov var2+1[di],al ; no, set new count
- ;
- mclock0:mov al,var2+1[di] ; reset timer
- mov var2[di],al ; /
- jmp short mclockx ; exit
- ;
- mclock1:dec byte ptr var2[di]; tick
- jz mclock0 ; branch if end of count
- mclockz:mov ah,0 ; else set output=0
- ;
- mclockx:mov outn[di],ah ; send output
- nextl ; exit
- ;==============================================================
- ; simple loop counter
- ; output: clock strobe
- ; input: 0: reset, 1: count, 2: offset
- ; 3x:countdown timer, 3z: copy of count
- ;--------------------------------------------------------------
- public _gamma
- _gamma: testv var1,-1 ; clock = 0
- jz gammaz ; yes, just exit
- hold var0 ; hold?
- jz gamma0 ; no, branch
- mov al,byte ptr cs:loops; get count
- and al,1 ; /
- mov var3[di],al ; reset clock counters
- jmp short gammaz ; split
- ;
- gamma0: getv ah,var1 ; get current count
- cmp ah,var3+1[di] ; same as before?
- jz gamma1 ; yes, branch
- cmp ah,1 ; set to 1?
- jnz gamma3 ; no, branch
- mov ah,2 ; yes, set to 2
- gamma3: mov al,byte ptr cs:loops; get count
- and al,1 ; /
- mov var3[di],ax ; /
- ;
- gamma1: getv al,var2 ; get offset trigger
- cmp al,ah ; out of range?
- jb gamma4 ; no, branch
- mov al,0 ; yes, zip it
- gamma4: cmp al,var3[di] ; same as count?
- jnz gamma2 ; no, branch
- mov byte ptr outn[di],1; yes, set output flag
- ;
- gamma2: inc byte ptr var3[di]; tick
- cmp ah,var3[di] ; reached count?
- jnz gammaz ; no, exit
- mov byte ptr var3[di],0; yes, reset timer
- gammaz: nextt ; exit
-
- ;==============================================================
- ; simple loop counter
- ; output: clock strobe
- ; input: 0: reset, 1: count
- ; 2x:countdown timer
- ;--------------------------------------------------------------
- public _muclk
- _muclk: testv var1,-1 ; clock = 0
- jz muclkz ; yes, just exit
- hold var0 ; hold?
- jnz muclk0 ; yes, reset & exit
- ;
- dec byte ptr var2[di]; count down
- jnz muclkz ; exit if not 0
- mov byte ptr outn[di],1; set output
- muclk0: getv al,var1 ; else get count
- mov var2[di],al ; put it away
- muclkz: nextt ; exit
- ;==============================================================
- ; Note Clock
- ; output: 0/Veloc input value
- ; inputs:
- ; 0: Reset & hold
- ; 1: Sync pulse
- ; 2: Note value 0-7, +10H tripplett, +20H dotted
- ; 3: Sustain value 0-255
- ; 4: Clock offset value
- ; 5: Velocity value
- ; 6x: note countdown
- ; 6+: nz = wait for sync with measure
- ; 7x: note-on clocks
- ; 7+: AB = has been initialized
- ; 8x: nz = sync countdown flag
- ; 8+: offset value changed flag
- ;--------------------------------------------------------------
-
- public _clock,_klock
- _klock: nop ; same routine, different address
- _clock:
- cmp byte ptr var7+1[di],0ABH; initialized yet?
- jz clock00 ; yes, branch
- mov byte ptr var7+1[di],0ABH; no, initialize
- ;
- initv var1,1 ; sync
- initv var2,3 ; note
- initv var5,1 ; velocity
- mov word ptr var6[di],0 ; flags
- mov byte ptr var7[di],0 ; flags
- ;
- clock00:hold var0 ; hold?
- jnz clock01 ; yes, go do it
- getv al,var4 ; change in offset value?
- cmp al,var8+1[di] ; /
- jz clock0 ; no, branch
- ;
- clock01:getv al,var4 ; get sync offset
- mov var8+1[di],al ; clear change flag
- inc al ; bump sync count so 0 --> 1
- mov var6+1[di],al ; set up sync offset count
- mov byte ptr outn[di],0 ; clear output
- mov byte ptr var6[di],0 ; clear note count
- jmp clockx ; exit
- ;
- clock0: test byte ptr var6+1[di],-1 ; waiting for sync?
- jz clock1 ; no, branch
- getv al,var1 ; sync start?
- or al,byte ptr var8[di] ; or countdown?
- jnz clock0a ; yes, branch
- jmp clockx ; no, exit
- ;
- clock0a:mov byte ptr var8[di],1 ; set offset flag
- dec byte ptr var6+1[di] ; countdown sync
- jz clock0b ; branch on if 0
- jmp clockx ; else exit
- clock0b:mov byte ptr var8[di],0 ; clear offset flag
- ;
- clock1: cmp byte ptr var6[di],0 ; at end of note?
- jz clock1b ; yes, branch
- jmp clock2 ; no, countdown
- ;
- clock1b:getv bl,var2 ; get note value
- mov dl,bl ; save in dl for dot/tripplet
- and bl,7 ; mask
- mov bh,0 ; else xlate to clocks
- add bx,offset dgroup:notetbl; /
- test dl,10h ; triplett?
- jz clock1c ; no, branch
- add bx,8 ; yes, bump table addr
- jmp short clock1d ; branch around dot
- clock1c:test dl,20h ; dot?
- jz clock1d ; no, branch
- add bx,16 ; yes, bump table addr
- clock1d:;
- mov cl,[bx] ; cl = clocks
- getv dl,var3 ; dl = sustain value
- ;
- mov al,1 ; al = 1 clock
- cmp dl,0 ; sustain = min
- jz clock1e ; yse, exit sust.
- ;
- mov al,cl ; al = nv (clocks)
- cmp dl,0ffh ; sustain = max
- jz clock1e ; yes, exit legato
- ;
- mul dl ; ax = nv * sust
- mov al,ah ; al = nv * sust / 256
- or al,al ; /
- jnz clock1e ; go if > 0
- inc al ; else make 1
- ;
- clock1e:mov var6[di],cl ; set new note value
- sub cl,al ; off = nv - on
- mov var7[di],cl ; set new off-time
- jmp short clock2a ; send out the note
- ;
- clock2: dec byte ptr var6[di] ; count down note
- jnz clock2a ; branch if not eon
- jmp clock1b ; if end of note, do a new one
- clock2a:mov al,0 ; setup for note-off
- mov ah,var6[di] ; get note clock countdown
- cmp ah,var7[di] ; > note-off time?
- jbe clock2b ; no, send note off
- getv al,var5 ; yes, send velocity
- clock2b:putn al ; send to output
- clockx: nextl ; exit
- ;==============================================================
- ; Loop Timer
- ; output: delayed pulse
- ; inputs: 0: strobe, 1: delay, 2: hold
- ; 3x: strobe clock, 4x: delay count, 4z: hold count
- ;--------------------------------------------------------------
- public _ltimer
- _ltimer:
- test byte ptr var4[di],-1 ; delay high?
- jz ltimer1 ; no, branch
- dec byte ptr var4[di] ; yes, count down
- jnz ltimerz ; exit if not finished
- ltimer0:mov byte ptr outn[di],1 ; else set output
- jmp short ltimerz ; then exit
- ;
- ltimer1:test byte ptr var4+1[di],-1 ; hold high?
- jz ltimer2 ; no, branch
- dec byte ptr var4+1[di] ; yes, count down
- jnz ltimerz ; exit if not finished
- mov byte ptr outn[di],0 ; else clear output
- jmp short ltimerz ; then exit
- ;
- ltimer2:tick var0,var3 ; strobe tick?
- jnc ltimerz ; no, just exit
- getv al,var1 ; yes, get delay
- getv ah,var2 ; ...get hold
- or ah,mprstf ; /
- mov var4[di],ax ; set them up
- or al,al ; delay = 0?
- jz ltimer0 ; yes, go set
- mov byte ptr outn[di],0 ; else clear output
- ltimerz:nextl ; exit
- ;==============================================================
- ; Clock Timer
- ; output: delayed pulse
- ; inputs: 0: clock, 1: strobe, 2: delay, 3: hold
- ; 4x: strobe clock, 5x: delay count, 5z: hold count
- ;--------------------------------------------------------------
- public _ctimer
- _ctimer:
- tickb1 var1,var4 ; strobe tick?
- jnc ctimer2 ; no, go on
- getv al,var2 ; yes, get delay
- getv ah,var3 ; ...get hold
- or ah,mprstf ; /
- mov var5[di],ax ; set them up
- or al,al ; delay = 0?
- jz ctimer0 ; yes, go set
- mov byte ptr outn[di],0 ; clear output
- jmp short ctimerz ; exit
- ;
- ctimer2:tick var0,var4 ; clock tick?
- jnc ctimerz ; no, branch
- ;
- test byte ptr var5[di],-1 ; delay high?
- jz ctimer1 ; no, branch
- dec byte ptr var5[di] ; yes, count down
- jnz ctimerz ; exit if not finished
- ctimer0:mov byte ptr outn[di],1 ; else set output
- jmp short ctimerz ; then exit
- ;
- ctimer1:test byte ptr var5+1[di],-1 ; hold high?
- jz ctimerz ; no, branch
- dec byte ptr var5+1[di] ; yes, count down
- jnz ctimerz ; exit if not finished
- mov byte ptr outn[di],0 ; else clear output
- ;
- ctimerz:nextl ; exit
- ;==============================================================
- ; Abs Timer
- ; output: delayed pulse
- ; inputs: 0: strobe, 1: delay, 2: hold, 3: period
- ; 4: timer value
- ; 5x: b0=delay flag, b1=hold flag
- ; 5z: clock
- ;--------------------------------------------------------------
- public _atimer
- _atimer:
- test byte ptr var5[di],1 ; delay high?
- jz atimer1 ; no, branch
- mov ax,cs:ticks ; yes, get timer value
- sub ax,var4[di] ; get lapsed time
- getv dl,var1 ; get delay time
- mov dh,0 ; /
- getv cl,var3 ; get period
- shl dx,cl ; bump
- cmp dx,ax ; out of gas?
- jnb atimerz ; no, exit
- mov ax,cs:ticks ; get current ticks
- mov var4[di],ax ; save it
- atimer0:mov byte ptr outn[di],1 ; set output
- hold var2 ; hold?
- jz atimer3 ; no, clear flag & exit
- mov byte ptr var5[di],2 ; yes, set hold flag
- jmp short atimerz ; then exit
- ;
- atimer1:test byte ptr var5[di],2 ; hold high?
- jz atimer2 ; no, branch
- mov ax,cs:ticks ; yes, get timer value
- sub ax,var4[di] ; get lapsed time
- getv dl,var2 ; get hold time
- mov dh,0 ; /
- getv cl,var3 ; get period
- shl dx,cl ; bump
- cmp dx,ax ; out of gas?
- jnb atimerz ; no, exit
- mov byte ptr outn[di],0 ; ...clear output
- atimer3:mov byte ptr var5[di],0 ; yes, clear flags
- jmp short atimerz ; then exit
- ;
- atimer2:tick var0,var5+1 ; strobe tick?
- jnc atimerz ; no, just exit
- mov ax,cs:ticks ; get current ticks
- mov var4[di],ax ; save it
- testv var1,-1 ; delay = 0
- jz atimer0 ; yes, go set
- mov byte ptr var5[di],1 ; else flag delay
- mov byte ptr outn[di],0 ; ...clear output
- atimerz:nextl ; exit
- ;==============================================================
- ; Seconds Timer
- ; output: delayed pulse
- ; inputs: 0: strobe, 1: delay, 2: hold, 3: period
- ; 4: timer value
- ; 5x: b0=delay flag, b1=hold flag
- ; 5z: clock
- ;--------------------------------------------------------------
- public _stimer
- _stimer:
- test byte ptr var5[di],1 ; delay high?
- jz stimer1 ; no, branch
- mov ax,cs:seconds ; yes, get timer value
- sub ax,var4[di] ; get lapsed time
- getv dl,var1 ; get delay time
- mov dh,0 ; /
- getv cl,var3 ; get period
- shl dx,cl ; bump
- cmp dx,ax ; out of gas?
- jnb stimerz ; no, exit
- mov ax,cs:seconds ; get current ticks
- mov var4[di],ax ; save it
- stimer0:mov byte ptr outn[di],1 ; set output
- hold var2 ; hold?
- jz stimer3 ; no, clear flag & exit
- mov byte ptr var5[di],2 ; yes, set hold flag
- jmp short stimerz ; then exit
- ;
- stimer1:test byte ptr var5[di],2 ; hold high?
- jz stimer2 ; no, branch
- mov ax,cs:seconds ; yes, get timer value
- sub ax,var4[di] ; get lapsed time
- getv dl,var2 ; get hold time
- mov dh,0 ; /
- getv cl,var3 ; get period
- shl dx,cl ; bump
- cmp dx,ax ; out of gas?
- jnb stimerz ; no, exit
- mov byte ptr outn[di],0 ; ...clear output
- stimer3:mov byte ptr var5[di],0 ; yes, clear flags
- jmp short stimerz ; then exit
- ;
- stimer2:tick var0,var5+1 ; strobe tick?
- jnc stimerz ; no, just exit
- mov ax,cs:seconds ; get current ticks
- mov var4[di],ax ; save it
- testv var1,-1 ; delay = 0
- jz stimer0 ; yes, go set
- mov byte ptr var5[di],1 ; else flag delay
- mov byte ptr outn[di],0 ; ...clear output
- stimerz:nextl ; exit
- ;==============================================================
- ; interference clock
- ; inputs: 0: hold/reset input
- ; 1-4: clock inputs
- ; 5x:
- ; 5z: clock ticks
- ; output: strobe upon any clock input
- ;--------------------------------------------------------------
- public _iclock
- _iclock:
- hold var0 ; hold?
- jz iclock0 ; no, branch
- jmp iclockz ; else exit
- ;
- iclock0:tick var1,var5+1 ; clock
- jnc iclock1 ; branch if no tick
- mov byte ptr outn[di],1 ; else set output
- iclock1:
- tickb1 var2,var5+1 ; clock
- jnc iclock2 ; branch if no tick
- mov byte ptr outn[di],1 ; else set output
- iclock2:
- tickb2 var3,var5+1 ; clock
- jnc iclock3 ; branch if no tick
- mov byte ptr outn[di],1 ; else set output
- iclock3:
- tickb3 var4,var5+1 ; clock
- jnc iclockz ; branch if no tick
- mov byte ptr outn[di],1 ; else set output
- iclockz:nextt ; exit
- ;==============================================================
- ; interference clock
- ; inputs: 0: clock
- ; 1: hold/reset input
- ; 2-5: count inputs
- ; 6x:
- ; 6z: clock ticks
- ; 7-8: change detectors
- ; 9-10:countdown registers
- ; output: strobe upon any clock input
- ;--------------------------------------------------------------
- public _kclock
- _kclock:
- hold var1 ; hold?
- jz kclocka ; no, branch
- kclockb:mov ax,101H ; yes, clear registers
- mov var9[di],ax ; /
- mov var10[di],ax ; /
- jmp kclockz ; exit
- ;
- kclocka:tick var0,var6+1 ; clock
- jc kclockd ; do it if tick
- jmp kclockz ; branch if no tick
- ;
- kclockd:getv al,var2 ; input change?
- getv ah,var3 ; /
- cmp ax,var7[di] ; /
- jz kclockc ; no, branch
- mov var7[di],ax ; yes, reset
- jmp short kclockb ; /
- kclockc:getv al,var4 ; input change?
- getv ah,var5 ; /
- cmp ax,var8[di] ; /
- jz kclock0 ; no, branch
- mov var8[di],ax ; yes, reset
- jmp short kclockb ; /
- ;
- kclock0:test byte ptr var9[di],-1 ; register zero'd?
- jz kclock1 ; yes, branch
- dec byte ptr var9[di] ; no, count down
- jnz kclock1 ; branch if not zero'd
- getv al,var2 ; else get count
- mov byte ptr var9[di],al ; reset register
- mov byte ptr outn[di],1 ; set output strobe
- ;
- kclock1:test byte ptr var9+1[di],-1 ; register zero'd?
- jz kclock2 ; yes, branch
- dec byte ptr var9+1[di] ; no, count down
- jnz kclock2 ; branch if not zero'd
- getv al,var3 ; else get count
- mov byte ptr var9+1[di],al ; reset register
- mov byte ptr outn[di],1 ; set output strobe
- ;
- kclock2:test byte ptr var10[di],-1 ; register zero'd?
- jz kclock3 ; yes, branch
- dec byte ptr var10[di] ; no, count down
- jnz kclock3 ; branch if not zero'd
- getv al,var4 ; else get count
- mov byte ptr var10[di],al ; reset register
- mov byte ptr outn[di],1 ; set output strobe
- ;
- kclock3:test byte ptr var10+1[di],-1 ; register zero'd?
- jz kclockz ; yes, branch
- dec byte ptr var10+1[di] ; no, count down
- jnz kclockz ; branch if not zero'd
- getv al,var5 ; else get count
- mov byte ptr var10+1[di],al ; reset register
- mov byte ptr outn[di],1 ; set output strobe
- ;
- kclockz:nextt ; exit
- ;==============================================================
- ; Index counter, incrementing
- ; inputs: 0: clock up, 1: hold/reset 2: inc/dec 3x: tick flag
- ; output: index
- ;--------------------------------------------------------------
- public _icount
- _icount:
- hold var1 ; hold?
- jz icount0 ; branch if no hold
- mov word ptr outn[di],100h; else zip output/index
- jmp short icountx ; exit with video update
- icount0:tick var0,var3 ; clock tick
- jc icount1 ; branch if there is a tick
- nextx ; else exit easy
- icount1:testv var2,-1 ; test inc/dec flag
- jnz icount2 ; branch if decrement
- inc word ptr outn[di]; inc index
- jmp next ; exit with video update
- icount2:dec word ptr outn[di]; dec index
- icountx:nextv ; exit
- ;==============================================================
- ; Index counter, with mask
- ; inputs: 0: clock up, 1: hold/reset 2: mask
- ; 3x: tick flag, 3z: tick count
- ; output: index
- ;--------------------------------------------------------------
- public _ocount
- _ocount:
- hold var1 ; hold?
- jz ocount0 ; branch if no hold
- mov byte ptr var3+1[di],0; else zip index
- jmp short ocountx ; exit with video update
- ocount0:tick var0,var3 ; clock tick
- jnc ocountx ; branch if no tick
- inc byte ptr var3+1[di]; inc index
- ocountx:getv al,var2 ; get the mask
- and al,var3+1[di] ; and with count
- putn al ; send it out
- nextv ; exit
- ;==============================================================
- ; Index counter, adding
- ; inputs: 0: clock up, 1: hold/reset 2: increment 3x: tick flag
- ; output: index
- ;--------------------------------------------------------------
- public _jcount
- _jcount:
- hold var1 ; hold?
- jz jcount0 ; branch if no hold
- mov word ptr outn[di],100H; else zip output/index
- jcountx:jmp next ; exit
- jcount0:tick var0,var3 ; clock tick
- jc jcount1 ; branch if there is a tick
- nextx ; else exit easy
- jcount1:getv al,var2 ; get the increment
- add outn[di],al ; add to the index
- nextv ; exit with video update
- ;==============================================================
- ; Index counter, adding with upper limit
- ; inputs: 0: clock up, 1: hold/reset 2: increment
- ; 3: inc/dec 4: top limit 5x: tick
- ; output: index
- ;--------------------------------------------------------------
- public _kcount
- _kcount:
- hold var1 ; hold?
- jz kcount0 ; branch if no hold
- testv var3,-1 ; counting up or down
- jnz kcounta ; branch if counting down
- mov al,0 ; up, set to bottom limit
- jmp short kcountb ; /
- kcounta:getv al,var4 ; down, set to top limit
- kcountb:mov ah,al ; /
- mov outn[di],ax ; /
- jmp next ; exit
- kcount0:tick var0,var5 ; clock tick
- jc kcount1 ; branch if there is a tick
- nextx ; else exit easy
- kcount1:mov dl,0 ; dl = 0 = bottom
- getv dh,var4 ; dh = the top limit
- jmp lcountk ; continue with lcount routine
- ;==============================================================
- ; Index counter, adding with upper and lower limit
- ; inputs: 0: clock up, 1: hold/reset 2: increment
- ; 3: inc/dec 4: top limit 5: bottom limit
- ; 6x: tick
- ; output: index
- ;--------------------------------------------------------------
- public _lcount
- _lcount:
- hold var1 ; hold?
- jz lcount0 ; branch if no hold
- testv var3,-1 ; counting up or down
- jnz lcounta ; branch if counting down
- getv al,var5 ; up, set to bottom limit
- jmp short lcountb ; /
- lcounta:getv al,var4 ; down, set to top limit
- lcountb:mov ah,al ; /
- mov outn[di],ax ; /
- jmp next ; exit
- lcount0:tick var0,var6 ; clock tick
- jc lcount1 ; branch if there is a tick
- nextx ; else exit easy
- lcount1:getv dl,var5 ; dl = the lower limit
- getv dh,var4 ; dh = the top limit
- cmp dh,dl ; top < bottom ?
- jnb lcountk ; no, branch
- xchg dh,dl ; yes, swap
- lcountk:inc dh ; bump so top is included
- getv al,var2 ; al = the increment
- getv ah,var3 ; ah = inc/dec
- test ah,-1 ; inc or dec?
- jnz lcount2 ; branch if dec
- ; ; counting up
- add al,outn+1[di] ; add inc to index
- cmp al,dh ; over the top?
- jna lcount3 ; no, branch
- sub al,dh ; yes, subtract top
- add al,dl ; add bottom
- lcount3:mov ah,al ; set new index
- dec al ; show index -1
- mov outn[di],ax ; /
- jmp next ; display & exit
- ; ; counting down
- lcount2:mov cl,outn+1[di] ; get index
- sub cl,al ; subtract inc
- jc lcount5 ; branch if rollover
- cmp cl,dl ; below the limit
- jnb lcount4 ; no, branch
- lcount5:add cl,dh ; yes, add top
- sub cl,dl ; subtract bottom
- lcount4:mov ch,cl ; set new index
- mov outn[di],cx ; /
- jmp next ; display & exit
-
- ;==============================================================
- ; Index counter, adding with upper and lower limit
- ; inputs: 0: clock up, 1: hold/reset 2: increment
- ; 3: inc/dec 4: top limit 5: bottom limit
- ; 6x: tick
- ; output: index
- ;--------------------------------------------------------------
- public _mcount
- _mcount:
- hold var1 ; hold?
- jz mcount0 ; branch if no hold
- testv var3,-1 ; counting up or down
- jnz mcounta ; branch if counting down
- getv al,var5 ; up, set to bottom limit
- jmp short mcountb ; /
- mcounta:getv al,var4 ; down, set to top limit
- mcountb:mov ah,al ; /
- mov outn[di],ax ; /
- jmp next ; exit
- mcount0:tick var0,var6 ; clock tick
- jc mcount1 ; branch if there is a tick
- nextx ; else exit easy
- mcount1:getv dl,var5 ; dl = the lower limit
- getv dh,var4 ; dh = the top limit
- cmp dh,dl ; top < bottom ?
- jnb mcountk ; no, branch
- xchg dh,dl ; yes, swap
- mcountk:inc dh ; bump so top is included
- getv al,var2 ; al = the increment
- getv ah,var3 ; ah = inc/dec
- test ah,-1 ; inc or dec?
- jnz mcount2 ; branch if dec
- ; ; counting up
- add al,outn+1[di] ; add inc to index
- cmp al,dh ; over the top?
- jna mcount3 ; no, branch
- mov al,dh ; get hi count
- sub al,dl ; get hi-lo
- shr al,1 ; /2
- mov ah,al ; hold
- shr al,1 ; 1/4
- add al,ah ; 3/4
- add al,dl ; offset from bottom
- mcount3:mov ah,al ; set new index
- mov outn[di],ax ; /
- jmp next ; display & exit
- ; ; counting down
- mcount2:mov cl,outn+1[di] ; get index
- sub cl,al ; subtract inc
- jc mcount5 ; branch if rollover
- cmp cl,dl ; below the limit
- jnb mcount4 ; no, branch
- mcount5:mov cl,dh ; get hi count
- sub cl,dl ; get hi-lo
- shr cl,1 ; 1/2
- shr cl,1 ; 1/4
- add cl,dl ; offset from bottom
- mcount4:mov ch,cl ; set new index
- mov outn[di],cx ; /
- jmp next ; display & exit
-
- ;==============================================================
- ; Index counter, incrementing, 16 bit
- ; inputs: 0: clock up
- ; 1: hold/reset
- ; 2: reset count lo
- ; 3: reset count hi
- ; 4: reset
- ; 5: shift output
- ; 6: up/down
- ; 7x:tick flag
- ; 8: index
- ; output: index
- ;--------------------------------------------------------------
- public _ncount
- _ncount:
- testv var4,-1 ; reset?
- jz ncount0 ; no, branch
- getv al,var2 ; yes, get reset count lo
- getv ah,var3 ; ... and reset count hi
- mov var8[di],ax ; reset
- ;
- ncount0:hold var1 ; hold?
- jnz ncountx ; branch if no hold
- ;
- tick var0,var7 ; clock tick
- jnc ncountx ; branch if no tick
- mov ax,1 ; setup for inc
- testv var6,-1 ; up or down
- jz ncount1 ; branch if up
- mov ax,-1 ; else setup for down
- ncount1:
- add var8[di],ax ; bump index
- ;
- ncountx:mov ax,word ptr var8[di] ; get the index
- getv cl,var5 ; get shift byte
- shr ax,cl ; bump right
- putn al ; send it out
- nextv ; exit
- ;==============================================================
- ; Sequencer/Switcher
- ; inputs: 0: stage addr, 1 - 16: stages, xl: old stage
- ; output: value of stage pointed to by var0
- ;
- public _wseq
- _wseq:
- getv al,var0 ; get variable0
- and al,15 ; 16 stages
- mov cl,al ; save it
- mov ch,var1+32[di] ; get saved last stage
- and ch,15 ; just to be safe
- mov var1+32[di],al ; store the new stage
- mov ah,0 ; make new stage into word
- add ax,ax ; /
- mov bx,ax ; bx = offset to the stage
- mov bx,var1[bx+di] ; get the value
- mov al,[bx] ; /
- putn al ; send to output
- ;--------------------------------------------------------------
- ; got the value, now clear old stage led, and set the new
- ;--------------------------------------------------------------
- cmp cl,ch ; have stages changed?
- jz wseqx ; no, then just exit
- gettag ; es:bx = screen addr of tag
- dec bx ; point to leds
- add ch,4 ; offset to 2nd var loc in screen
- mov al,160 ; point to stage led
- mul ch ; ax = offset to old stage led
- mov di,ax ; put in di for indexing
- mov byte ptr es:[bx+di],yellow; turn the led off
- add cl,4 ; offset to 2nd var loc in screen
- mov al,160 ; point to stage led
- mul cl ; ax = offset to new stage led
- mov di,ax ; put in di for indexing
- mov byte ptr es:[bx+di],hi+red; turn the led on
- wseqx:
- mov di,2[si] ;; set di pointing to variable list
- nextv ; show the output
- ;==============================================================
- ; Sequencer/Switcher
- ; inputs: 0: stage addr, 1 - 8: stages, xl: old stage
- ; output: value of stage pointed to by var0
- ;
- public _xseq
- _xseq:
- getv al,var0 ; get variable0
- and al,7 ; 8 stages
- mov cl,al ; save it
- mov ch,var1+16[di] ; get saved last stage
- and ch,7 ; just to be safe
- mov var1+16[di],al ; store the new stage
- mov ah,0 ; make new stage into word
- add ax,ax ; /
- mov bx,ax ; bx = offset to the stage
- mov bx,var1[bx+di] ; get the value
- mov al,[bx] ; /
- putn al ; send to output
- ;--------------------------------------------------------------
- ; got the value, now clear old stage led, and set the new
- ;--------------------------------------------------------------
- cmp cl,ch ; have stages changed?
- jz xseqx ; no, then just exit
- gettag ; es:bx = screen addr of tag
- dec bx ; point to leds
- add ch,4 ; offset to 2nd var loc in screen
- mov al,160 ; point to stage led
- mul ch ; ax = offset to old stage led
- mov di,ax ; put in di for indexing
- mov byte ptr es:[bx+di],yellow; turn the led off
- add cl,4 ; offset to 2nd var loc in screen
- mov al,160 ; point to stage led
- mul cl ; ax = offset to new stage led
- mov di,ax ; put in di for indexing
- mov byte ptr es:[bx+di],hi+red; turn the led on
- xseqx:
- mov di,2[si] ; set di pointing to variable list
- nextv ; show the output
- ;==============================================================
- ; Sequencer/Switcher
- ; inputs: 0: stage addr, 1 - 4: stages, xl: old stage
- ; output: value of stage pointed to by var0
- ;
- public _yseq
- _yseq:
- getv al,var0 ; get variable0
- and al,3 ; 4 stages
- mov cl,al ; save it
- mov ch,var1+8[di] ; get saved last stage
- and ch,3 ; just to be safe
- mov var1+8[di],al ; store the new stage
- mov ah,0 ; make new stage into word
- add ax,ax ; /
- mov bx,ax ; bx = offset to the stage
- mov bx,var1[bx+di] ; get the value
- mov al,[bx] ; /
- putn al ; send to output
- ;--------------------------------------------------------------
- ; got the value, now clear old stage led, and set the new
- ;--------------------------------------------------------------
- cmp cl,ch ; have stages changed?
- jz yseqx ; no, then just exit
- gettag ; es:bx = screen addr of tag
- dec bx ; point to leds
- add ch,4 ; offset to 2nd var loc in screen
- mov al,160 ; point to stage led
- mul ch ; ax = offset to old stage led
- mov di,ax ; put in di for indexing
- mov byte ptr es:[bx+di],yellow; turn the led off
- add cl,4 ; offset to 2nd var loc in screen
- mov al,160 ; point to stage led
- mul cl ; ax = offset to new stage led
- mov di,ax ; put in di for indexing
- mov byte ptr es:[bx+di],hi+red; turn the led on
- yseqx:
- mov di,2[si] ; set di pointing to variable list
- nextv ; show the output
- ;==============================================================
- ; Sequencer/Switcher
- ; inputs: 0: stage addr, 1 - 2: stages, xl: old stage
- ; output: value of stage pointed to by var0
- ;
- public _zseq
- _zseq:
- getv al,var0 ; get variable0
- and al,1 ; 1 stages
- mov cl,al ; save it
- mov ch,var1+4[di] ; get saved last stage
- and ch,1 ; just to be safe
- mov var1+4[di],al ; store the new stage
- mov ah,0 ; make new stage into word
- add ax,ax ; /
- mov bx,ax ; bx = offset to the stage
- mov bx,var1[bx+di] ; get the value
- mov al,[bx] ; /
- putn al ; send to output
- ;--------------------------------------------------------------
- ; got the value, now clear old stage led, and set the new
- ;--------------------------------------------------------------
- cmp cl,ch ; have stages changed?
- jz zseqx ; no, then just exit
- gettag ; es:bx = screen addr of tag
- dec bx ; point to leds
- add ch,4 ; offset to 2nd var loc in screen
- mov al,160 ; point to stage led
- mul ch ; ax = offset to old stage led
- mov di,ax ; put in di for indexing
- mov byte ptr es:[bx+di],yellow; turn the led off
- add cl,4 ; offset to 2nd var loc in screen
- mov al,160 ; point to stage led
- mul cl ; ax = offset to new stage led
- mov di,ax ; put in di for indexing
- mov byte ptr es:[bx+di],hi+red; turn the led on
- zseqx:
- mov di,2[si] ; set di pointing to variable list
- nextv ; show the output
- ;==============================================================
- ; Sequencer/Switcher
- ; output: "a" input if var0 AND var1 = 0, else "b" input
- ; inputs:
- ; 0, 1: test inputs, ANDed to give flag
- ; 2: input stage "a"
- ; 3: input stage "b"
- ;
- public _useq
- _useq: getv dl,var0 ; get flag vars
- getv dh,var1 ; /
- mov ch,yellow ; set up led colors
- mov cl,red+hi ; /
- getv al,var2 ; get "a" input
- ;
- and dh,dl ; test
- jz useq0 ; branch if "b" input
- xchg ch,cl ; else setup for 2nd
- getv al,var3 ; get "b" input
- ;
- useq0: gettag ; get screen address of leds
- add bx,799 ; set up input leds
- mov es:[bx],cl ; do the leds
- mov es:160[bx],ch ; /
- ;
- putn al ; send to output
- nextv ; exit
- ;==============================================================
- ; Sequencer/Switcher
- ; output: "a" input if var0 AND var1 = 0, else "b" input
- ; inputs:
- ; 0, 1: test inputs, ANDed to give flag
- ; 2: input stage "a"
- ; 3: input stage "b"
- ; 4: offset
- ;
- public _vseq
- _vseq: getv dl,var0 ; get flag vars
- getv dh,var1 ; /
- mov ch,yellow ; set up led colors
- mov cl,red+hi ; /
- getv al,var2 ; get "a" input
- ;
- and dh,dl ; test
- jz vseq0 ; branch if "b" input
- xchg ch,cl ; else setup for 2nd
- getv al,var3 ; get "b" input
- ;
- vseq0: gettag ; get screen address of leds
- add bx,799 ; set up input leds
- mov es:[bx],cl ; do the leds
- mov es:160[bx],ch ; /
- ;
- getv ah,var4 ; get the offset
- add al,ah ; put them together
- putn al ; send to output
- nextv ; exit
- ;==============================================================
- ; Pass input thru to output on nz test input, zero on low
- ; inputs: 0: switch
- ; 1: value1, 2: value2
- ; output: value/0
- ;--------------------------------------------------------------
- public _passt
- _passt: getv al,var1 ; al = input a
- mov ch,yellow ; set up led colors
- mov cl,red+hi ; /
- testv var0,-1 ; test a/b switch
- jz passt1 ; branch if 1st input
- ;
- getv al,var2 ; al = input b
- xchg ch,cl ; else setup for 2nd
- ;
- passt1: putn al ; put it away
- ;
- gettag ; get screen address of leds
- dec bx ; /
- mov bp,bx ; save it
- add bx,640 ; bx = screen addr of 1st led
- mov es:[bx],cl ; do the leds
- mov es:160[bx],ch ; /
- ;
- nextv ; show it
- ;==============================================================
- ; Pass input thru to output on nz test input, zero on low
- ; inputs: 0: switch
- ; 1: value1, 2: value2, 3: offset
- ; output: value/0
- ;--------------------------------------------------------------
- public _passq
- _passq: getv al,var1 ; al = input a
- mov ch,yellow ; set up led colors
- mov cl,red+hi ; /
- testv var0,-1 ; test a/b switch
- jz passq1 ; branch if 1st input
- ;
- getv al,var2 ; al = input b
- xchg ch,cl ; else setup for 2nd
- ;
- passq1: getv ah,var3 ; get offset
- add al,ah ; /
- putn al ; put it away
- ;
- gettag ; get screen address of leds
- dec bx ; /
- mov bp,bx ; save it
- add bx,640 ; bx = screen addr of 1st led
- mov es:[bx],cl ; do the leds
- mov es:160[bx],ch ; /
- ;
- nextv ; show it
- ;==============================================================
- ; Standard 256 byte sequencer with input mask
- ; inputs: 0: address 1: write enable, 2: input, 3: input mask
- ; 4x: module number, 4z, init flag
- ; output: byte addressed by address
- ;--------------------------------------------------------------
- public _pseq
- _pseq: cmp byte ptr var4+1[di],0abh; initialized?
- jnz pseq2 ; no, branch
- test usrflg,1 ; user input
- jnz pseq1 ; yes, no go
- ;
- mov ax,seg bufsp ; setup seg register
- mov es,ax ; es = seg addr
- getv dl,var0 ; get address
- mov dh,0 ; /
- mov bh,var4[di] ; get hi address
- mov bl,0 ; /
- add bx,dx ; set up as index
- mov dx,bx ; save
- mov al,es:[bx] ; get the byte
- putn al ; send it out
- ;
- testv var1,-1 ; write enabled?
- jz pseq1 ; no, branch
- getv al,var2 ; yes, get input
- getv ah,var3 ; get mask
- and al,ah ; mask the input
- not ah ; complement
- mov bx,dx ; get address again
- and es:[bx],ah ; clear old bits
- or es:[bx],al ; put in new bits
- ; or _mpab,8 ; set buffer used flag
- pseq1: nextv ; exit with video update
- ;
- pseq2: mov al,modnum ; get module number
- mov var4[di],al ; save it
- mov byte ptr var4+1[di],0abh; set init flag
- initv var3,0ffh ; mask <- FF
- gettag ; es:bx = screen addr of tag
- tohex ; convert to hex
- mov es:-2[bx],al ; show the default number
- nextx ; exit
- ;--------------------------------------------------------------
- ; magenta input
- ;
- public upseq
- upseq: pop ax ; stack bullshit
- mov cmdflg,10 ; set up special routine
- mov special,offset upseqx
- mov di,varsav ; point to variable list
- mov al,outn[di] ; get the output value
- mov var4[di],al ; save
- jmp workx ; on to the next stage
- ;
- upseqx: mov di,varsav ; point to variable list
- mov al,outn[di] ; get the new channel
- xchg var4[di],al ; set it, get orig patch
- mov outn[di],al ; restore
- jmp _cancel ; exit
- ;==============================================================
- ; Standard 256 byte sequencer with offset
- ; inputs: 0: address, 1: offset, 2x: mod #, 2z: init flag
- ; output: byte addressed by address
- ;--------------------------------------------------------------
- public _qseq,_rseq,_sseq,_tseq
- _tseq: nop
- _sseq: nop
- _rseq: nop
- _qseq: cmp byte ptr var2+1[di],0abh; initialized?
- jnz qseq1 ; no, branch
- test usrflg,1 ; user input
- jnz qseq0 ; yes, no go
- ;
- mov ax,seg bufsp ; setup seg register
- mov es,ax ; es = seg addr
- getv dl,var1 ; get offset
- mov dh,0 ; (not needed)
- getv bl,var0 ; get address
- mov bh,var2[di] ; get hi address
- add bl,dl ; set up as index
- mov al,es:[bx] ; get the byte
- putn al ; send it out
- qseq0: nextv ; exit with video update
- ;
- qseq1: mov al,modnum ; get module number
- mov var2[di],al ; save it
- mov byte ptr var2+1[di],0abh; set init flag
- gettag ; es:bx = screen addr of tag
- tohex ; convert to hex
- mov es:-2[bx],al ; show the default number
- nextx ; exit
- ;--------------------------------------------------------------
- ; magenta input
- ;
- public uqseq
- uqseq: pop ax ; stack bullshit
- mov cmdflg,10 ; set up special routine
- mov special,offset uqseqx
- mov di,varsav ; point to variable list
- mov al,outn[di] ; get the output value
- mov var2[di],al ; save
- jmp workx ; on to the next stage
- ;
- uqseqx: mov di,varsav ; point to variable list
- mov al,outn[di] ; get the new channel
- xchg var2[di],al ; set it, get orig patch
- mov outn[di],al ; restore
- jmp _cancel ; exit
- ;==============================================================
- ; 65K byte Sequencer with input mask
- ; inputs: 0: address lo, 1: address hi,
- ; 2: write enable, 3: input, 4: input mask, 5x: init flag
- ; output: byte addressed by address + offset
- ;--------------------------------------------------------------
- public _puseq
- _puseq:
- cmp byte ptr var5[di],0abh; initialized?
- jnz puseq2 ; no, branch
- 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
- mov bx,dx ; set up as index
- mov al,es:[bx] ; get the byte
- putn al ; send it out
- ;
- testv var2,-1 ; write enabled?
- jz puseq1 ; no, branch
- getv al,var3 ; yes, get input
- getv ah,var4 ; get mask
- and al,ah ; mask the input
- not ah ; complement
- mov bx,dx ; get address again
- and es:[bx],ah ; clear old bits
- or es:[bx],al ; put in new bits
- ; or _mpab,4 ; set buffer used flag
- puseq1: nextv ; exit with video update
- ;
- puseq2: mov al,modnum ; get module number
- mov byte ptr var5[di],0abh; set init flag
- initv var4,0ffh ; mask <- FF
- nextx ; exit
- ;==============================================================
- ; 65K byte sequencer with offset
- ; inputs: 0: address lo, 1: address hi, 2: offset
- ; output: byte addressed by address
- ;--------------------------------------------------------------
-
- public _quseq,_ruseq,_suseq,_tuseq
- _tuseq: nop
- _suseq: nop
- _ruseq: nop
- _quseq:
- 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
- putn al ; send it out
- nextv ; exit with video update
- ;==============================================================
- ; Delay Sequencer
-
- ; inputs: 0: clock, 1: page address, 2: read offset, 3: write enable,
- ; 4: input, 5: offset, 6x: clock tick
-
- ; inputs: 0: clock
- ; 1: input
- ; 2: read offset
- ; 3: write enable
- ; 4: offset
- ; 5x: page address
- ; 5z: index
- ; 6x: clock tick
- ; 6z: init flag
- ; output: byte addressed by index (hi byte of output addr) + var2
- ; AND 15 + (var1 * 16), AFTER write operation.
- ; Thus, a read offset of 0 causes the output to track the input,
- ; an offset of 1 tracks 1 clock behind, etc.
- ;--------------------------------------------------------------
- public _euseq
- _euseq:
- cmp byte ptr var6+1[di],0abh; initialized?
- jnz euseqi ; no, go do it
- ;
- tick var0,var6 ; clock tick
- jnc euseqx ; exit if no tick
- ;
- mov ax,seg buftu ; setup seg register
- mov cl,var5[di] ; ch = buffer page addr low
- mov ch,0 ; cx = buffer page addr
- add ax,cx ; ax = seg addr of 16 byte buffer
- mov es,ax ; es = seg addr
- mov ah,var5+1[di] ; ah = index offset
- ;
- testv var3,-1 ; write enabled?
- jz euseq2 ; no, branch
- getv al,var1 ; yes, get input
- mov bl,ah ; set up offset
- and bl,15 ; 15 bytes in the buffer
- mov bh,0 ; /
- mov es:[bx],al ; write the byte
- ;
- euseq2: getv al,var2 ; al = read offset
- neg al ; read behind
- add al,ah ; al = index-offset
- and al,15 ; 15 bytes in the buffer
- mov bl,al ; set up an index pointer
- mov bh,0 ; /
- mov al,es:[bx] ; get the read byte
- getv dl,var4 ; get offset
- add al,dl ; add to output
- putn al ; send it out
- ;
- inc ah ; bump index
- mov var5+1[di],ah ; set the new index
- nextv ; exit with video update
- euseqx: nextx
- ;
- euseqi: mov byte ptr var6+1[di],0abh; set init flag
- initv var3,1 ; write enable
- mov al,modnum ; get module number
- mov ah,0 ; zip index
- mov var5[di],ax ; save it
- gettag ; es:bx = screen addr of tag
- tohex ; convert to hex
- mov es:-2[bx],al ; show the default number
- nextx ; exit
- ;--------------------------------------------------------------
- ; magenta input
- ;
- public ueuseq
- ueuseq: pop ax ; stack bullshit
- mov cmdflg,10 ; set up special routine
- mov special,offset ueuseqx
- mov di,varsav ; point to variable list
- mov al,outn[di] ; get the output value
- mov var5[di],al ; save
- jmp workx ; on to the next stage
- ;
- ueuseqx:mov di,varsav ; point to variable list
- mov al,outn[di] ; get the new channel
- xchg var5[di],al ; set it, get orig patch
- mov outn[di],al ; restore
- jmp _cancel ; exit
- ;==============================================================
- ; set/clear mute flags
- ; inputs: 0: flags 0-7, 1: flags 8-15,
- ; 2: shift, 3: mask
- ; 4x: last var0, 4z: last var1
- ;
- ; output: 16bit mute word, shifted & masked
- ;--------------------------------------------------------------
- public _domute
- _domute:test valflg,-1 ; inputting now
- jnz domutex ; yes, just get them
- ;
- getv al,var0 ; get mute flags
- getv ah,var1 ; /
- not ax ; flip polarity
- ;
- mov dx,ax ; save it
- xor ax,var4[di] ; bits set are changes
- mov var4[di],dx ; save the new value
- mov cx,ax ; save flag bits
- not ax ; flip flag bits
- and mute,ax ; strip changed bits
- and cx,dx ; get new changed bits
- or mute,cx ; put them away
- ;
- domutex:mov dx,mute ; get the mute word
- getv cl,var2 ; get the shift
- ror dx,cl ; shift right
- not dl ; flip bits
- getv al,var3 ; get mask
- and al,dl ; mask the mute flags
- putn al ; send it out
- nextv ; exit
- ;==============================================================
- ; External call via software interrupt
- ; output: returned value of AL
- ; inputs:
- ; 0: clock
- ; 1: interrupt number
- ; 2: value loaded into AH
- ; 3: value loaded into AL
- ; 4: value loaded into BH
- ; 5: value loaded into BL
- ; 6: value loaded into CH
- ; 7: value loaded into CL
- ; 8: value loaded into DH
- ; 9: value loaded into DL
- ; 10x: clock tick
- ;--------------------------------------------------------------
- public _xcall
- _xcall: tick var0,var10 ; tick clock
- jnc xcallx ; exit if no tick
- ;
- getv al,var1 ; get the interrupt number
- test al,-1 ; anything there
- jz xcallx ; no, exit
- ;
- mov byte ptr cs:xcalli+1,al; set up the int number
- getv ah,var2 ; load registers
- getv al,var3 ; /
- getv ch,var4 ; /
- getv cl,var5 ; /
- mov bp,cx ; /
- getv ch,var6 ; /
- getv cl,var7 ; /
- getv dh,var8 ; /
- getv dl,var9 ; /
- mov bx,bp ; /
- push si ; save needed registers
- push di ; /
- push ds ; /
- xcalli: int 64 ; go do it
- pop ds ; restore registers
- pop di ; /
- pop si ; /
- mov xcax,ax ; save registers
- mov xcbx,bx ; /
- mov xccx,cx ; /
- mov xcdx,dx ; /
- pushf ; get flags
- pop ax ; /
- putn al ; send low flags to output
- xcallx: nextv ; exit
- ;==============================================================
- ; read a register after xcall
- ; output: xcall register storage
- ; inputs: 0: strobe, 1: register number, 2x: clock tick
- ; 0 = al, 1 = ah, 2 = bl, 3 = bh,
- ; 4 = cl, 5 = bh, 6 = dl, 7 = dh
- ;--------------------------------------------------------------
- public _rcall
- _rcall: tick var0,var2 ; clock tick
- jnc rcallx ; exit if no clock
- getv al,var1 ; get the register number
- and ax,7 ; 8 registers allowed
- mov bx,offset dgroup:xcax; get table location
- add bx,ax ; add offset
- mov al,[bx] ; get the register
- putn al ; send it out
- rcallx: nextv ; exit
- ;==============================================================
- ; read a byte from the keyboard
- ; output: ascii keyboard data
- ; inputs: 0: hold
- ;--------------------------------------------------------------
- public _xkbd
- _xkbd:
- hold var0 ; hold?
- jnz xkbdx ; yes, exit
- and byte ptr outn[di],7fh; strip old key flag
- mov ah,6 ; dos direct console i/o
- mov dl,0ffh ; input request
- int 21h ; call dos
- jz xkbdx ; exit if no input
- or al,al ; function key
- jz xkbd0 ; yes, don't set flag
- or al,80H ; set new key flag
- xkbd0: putn al ; send it out
- xkbdx: nextv ; exit
- ;==============================================================
- ; read a byte from MIDI to s-sequencer
- ; output: index into s-sequencer
- ; inputs: 0: reset strobe, 1: enable, 2x: tick
- ;--------------------------------------------------------------
- public _xmidii
- _xmidii:
- tick var0,var2 ; strobe tick?
- jnc xmidii0 ; no, branch
- mov cs:midatix,0 ; yes, clear index
- ;
- xmidii0:getv al,var1 ; get write enable flag
- mov cs:misend,al ; set/clear the flag
- ;
- mov al,cs:midatix ; get index
- putn al ; send it out
- nextv ; exit
- ;==============================================================
- ; show output buffer status
- ; inputs: none
- ; output: flag bits 0,1 set if output buffer not empty
- ;--------------------------------------------------------------
- public _tstmob
- _tstmob:call tstmob ; check it
- putn al ; send it out
- nextl ; show it
- ;==============================================================
- ; show mpu input flags, set mpu input mask
- ; 0 = no input, 1=mpu#1, 2=mpu#2
- ; inputs: 0: reset input flag
- ; 1: mpu input mask
- ; 2x init flag
- ; output: mpu input flags
- ;--------------------------------------------------------------
- public _mpuins
- _mpuins:cmp byte ptr var2[di],0abh ; initialized?
- jnz mpuins0 ; no, branch
- ;
- getv al,var1 ; get mask byte
- mov cs:_mpuinm,al ; set mask
- ;
- mov al,cs:_mpuinf ; get mpu input flag
- putn al ; send it out
- ;
- testv var0,-1 ; want to clear mpu flag?
- jnz mpuins1 ; no, branch
- mov cs:_mpuinf,0 ; clear mpu flag
- ;
- mpuins1:nextl ; show it
- ;
- mpuins0:mov byte ptr var2[di],0abh ; no, set init values
- initv var1,3 ; default is all ok
- nextx ; exit
- ;;==============================================================
- ; output a byte to output port
- ; output: none
- ; inputs:
- ; 0: clock
- ; 1: value to be output
- ; 2: output port address hi
- ; 3: output port address lo
- ; 4x: clock tick
- ;--------------------------------------------------------------
- public _outpb
- _outpb: tick var0,var4 ; clock tick
- jnc outpbx ; exit if no clock
- getv dh,var2 ; get the address
- getv dl,var3 ; /
- getv al,var1 ; get the value
- out dx,al ; send it out
- outpbx: nextx ; exit
- ;==============================================================
- ; input a byte from input port
- ; output: value from port
- ; inputs:
- ; 0: clock
- ; 1: input port address hi
- ; 2: input port address lo
- ; 3x: clock tick
- ;--------------------------------------------------------------
- public _inptb
- _inptb: tick var0,var3 ; clock tick
- jnc inptbx ; exit if no clock
- getv dh,var1 ; get the address
- getv dl,var2 ; /
- in al,dx ; get the value from port
- putn al ; send it
- inptbx: nextv ; exit & show
- ;==============================================================
- ; input a byte from memory
- ; output: value from memory
- ; inputs:
- ; 0: clock
- ; 1: seg addr hi
- ; 2: input port address hi
- ; 3: input port address lo
- ; 4x: clock tick
- ;--------------------------------------------------------------
- public _peek
- _peek: tick var0,var4 ; clock tick
- jnc peekx ; exit if no clock
- getv dh,var1 ; get seg hi
- getv ah,var2 ; get address hi
- getv bl,var3 ; get address lo
- mov bh,ah ; bx = address
- mov dl,0 ; dx = seg
- mov es,dx ; es = seg
- mov al,es:[bx] ; get the byte
- putn al ; send it
- peekx: nextv ; exit & show
- ;==============================================================
- ; output a byte to memory
- ; output: none
- ; inputs:
- ; 0: clock
- ; 1: value to be output
- ; 2: seg addr hi
- ; 3: input port address hi
- ; 4: input port address lo
- ; 5x: clock tick
- ;--------------------------------------------------------------
- public _poke
- _poke: tick var0,var5 ; clock tick
- jnc pokex ; exit if no clock
- getv al,var1 ; get the value
- getv dh,var2 ; get seg hi
- getv ah,var3 ; get address hi
- getv bl,var4 ; get address lo
- mov bh,ah ; bx = address
- mov dl,0 ; dx = seg
- mov es,dx ; es = seg
- mov es:[bx],al ; put the byte
- putn al ; send it
- pokex: nextx ; exit
- ;==============================================================
- ; System Exclusive Receive
- ; inputs:
- ; 0: Address Low of sequencer "S" where data will go
- ; 1: Address High of sequencer "S"
- ; 2: Strobe to start receive
- ; 3: Shift output value
- ; 4xz: Index into seq "s"
- ; 5x: strobe tick
- ; output: Next available seq addr, shifted right by input 3
- ;--------------------------------------------------------------
- public _sxget
- _sxget: tick var2,var5 ; wanna do it?
- jc sxget0 ; yes, branch
- jmp sxgetx ; no, exit to readout
- ;
- sxget0: mov es,4[di] ; get seg addr
- mov bx,6[di] ; get module screen address
- mov al,'X' ; set output byte
- mov es:320[bx],al ; put to the screen
- mov es:322[bx],al ; /
- mov ax,80H ; to set hi bit
- mov outn[di],ax ; trash output
- or es:321[bx],al ; put to the screen
- or es:323[bx],al ; /
- ;
- sxget6: call allclr ; clear midi channel
- ;
- mov word ptr var4[di],-2 ; setup error flag
- mov cs:miflag,0 ; clear input data flag
- ;
- 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
- mov bx,dx ; set up as index
- ;
- mov bp,cs:ticks ; get timer
- add bp,11640 ; timeout in 20 sec.
- ;
- sxget1: test cs:miflag,-1 ; anything there?
- jnz sxget2 ; yes, branch
- cmp bp,cs:ticks ; timeout?
- jnz sxget1 ; no, keep looking
- jmp sxgetx ; yes, exit
- ;
- sxget2: mov cs:miflag,0 ; clear input flag
- cmp cs:midata,0f0h ; system exclusive?
- jnz sxget1 ; no, keep looking
- mov byte ptr es:[bx],0f0h ; yes, send the data
- inc bx ; bump index
- jz sxgetx ; exit if index overflow
- ;
- sxget3: test cs:miflag,-1 ; anything there?
- jnz sxget4 ; yes, branch
- cmp bp,cs:ticks ; timeout?
- jnz sxget3 ; no, keep looking
- ;
- sxget4: mov cs:miflag,0 ; clear input flag
- mov al,cs:midata ; get the data
- mov es:[bx],al ; put it in the seq memory
- cmp al,0f7h ; EOX?
- jz sxget5 ; yes, branch
- inc bx ; bump index
- jz sxgetx ; exit if index overflow
- jmp short sxget3 ; else back to the loop
- ;
- sxget5: mov var4[di],bx ; set the new index
- mov _header+7,1 ; set buffer used flag
- ;
- sxgetx: mov ax,var4[di] ; get the index
- inc ax ; bump one
- getv cl,var3 ; get shift byte
- shr ax,cl ; bump right
- putn al ; send it out
- mov al,7fH ; to set lo bit
- mov es,4[di] ; get seg addr
- mov bx,6[di] ; get module screen address
- and es:321[bx],al ; put to the screen
- and es:323[bx],al ; /
- nextv ; exit
- ;==============================================================
- ; System Exclusive Send
- ; inputs:
- ; 0: Address Low of sequencer "S" where data is found
- ; 1: Address High of sequencer "S"
- ; 2: Strobe to start send
- ; 3: Shift output value
- ; 4xz: Index into seq "s"
- ; 5x: strobe tick
- ; output: Next available seq addr, shifted right by input 3
- ;--------------------------------------------------------------
- public _sxput
- _sxput: tick var2,var5 ; wanna do it?
- jc sxput0 ; yes, branch
- jmp sxputx ; no, exit to readout
- ;
- sxput0: mov word ptr var4[di],-2 ; setup error flag
- mov midip,0 ; set midi port 0
- ;
- mov es,4[di] ; get seg addr
- mov bx,6[di] ; get module screen address
- mov al,'X' ; set output byte
- mov es:320[bx],al ; put to the screen
- mov es:322[bx],al ; /
- mov ax,80H ; to set hi bit
- mov outn[di],ax ; trash output
- or es:321[bx],al ; put to the screen
- or es:323[bx],al ; /
- ;
- 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
- mov bp,dx ; set up as index
- ;
- sxput1: call allclr ; clear midi channels
- ;
- sxput2: mov al,es:[bp] ; get the data byte
- mov ah,al ; save in ah
- call allmidi ; send it to buffer
- sendmb ; send it to MIDI
- ;
- cmp ah,0f7h ; EOX?
- jz sxput3 ; yes, branch
- inc bp ; bump index
- jz sxputx ; exit if index overflow
- jmp short sxput2 ; else back to the loop
- ;
- sxput3: mov var4[di],bp ; set the new index
- ;
- sxputx: mov ax,var4[di] ; get the index
- inc ax ; bump one
- getv cl,var3 ; get shift byte
- shr ax,cl ; bump right
- putn al ; send it out
- mov al,7fH ; to set lo bit
- mov es,4[di] ; get seg addr
- mov bx,6[di] ; get module screen address
- and es:321[bx],al ; put to the screen
- and es:323[bx],al ; /
- nextv ; exit
- ;==============================================================
- ; MIDI Program change
- ; inputs:
- ; 0: channel
- ; 1: delay
- ; 2: strobe
- ; 3: input
- ; 4x: strobe tick
- ; output: none
- ;--------------------------------------------------------------
- public _patcho
- _patcho:
- test lodflg,-1 ; load happen?
- jnz patcho1 ; yes, force change
- test clrchf,3 ; clear chan flag?
- jz patcho2 ; yes, force change
- or clrchf,2 ; setup to clear
- jmp patcho1 ; go do it
- ;
- patcho2:tick var2,var4 ; clock tick
- jnc patchox ; exit if no strobe
- ;
- patcho1:call allclr ; clear all midi channels
- getv al,var0 ; get channel
- mchan al ; /
- or al,0c0H ; MIDI Program Change
- call tomidi ; send it to midi
- ;
- getv al,var3 ; get value input
- mov outn[di],al ; send to output
- and al,127 ; strip msb
- call tomidi ; send to midi
- ;
- getv al,var1 ; get delay value
- or al,al ; split if 0
- jz patchox ; /
- mov ah,0 ; make it a word
- add ax,cs:ticks ; add current ticks
- patcho0:cmp al,byte ptr cs:ticks ; reached it yet?
- jnz patcho0 ; no, loop
- patchox:nextv
- ;==============================================================
- ; Programmer output values
- ; inputs: 0x: channel
- ; output: sequencer send to the controller
- ;--------------------------------------------------------------
- public _pcouta
- _pcouta:cmp byte ptr var0+1[di],0abh; initialized?
- jz pcouta0 ; yes, branch
- ;
- pcouti: mov al,modnum ; get module number
- mov var0[di],al ; save it
-
- gettag ; es:bx = screen addr of tag
- tohex ; convert to hex
- mov es:-2[bx],al ; show the default number
- mov byte ptr var0+1[di],0abh; set init flag
- nextx
- ;
- pcouta0:test usrflg,1 ; user input
- jnz pcoutax ; yes, no go
- mov bl,var0[di] ; get channel
- mov bh,0 ; bx = channel
- add bx,offset dgroup:pcva ; add table to offset
- mov al,[bx] ; get the value
- putn al ; send it out
- pcoutax:nextv ; exit with display
- ;--------------------------------------------------------------
- public _pcoutb
- _pcoutb:cmp byte ptr var0+1[di],0abh; initialized?
- jz pcoutb0 ; yes, branch
- jmp pcouti ; no, initialize
- ;
- pcoutb0:test usrflg,1 ; user input
- jnz pcoutbx ; yes, no go
- mov bl,var0[di] ; get channel
- mov bh,0 ; bx = channel
- add bx,offset dgroup:pcvb ; add table to offset
- mov al,[bx] ; get the value
- putn al ; send it out
- pcoutbx:nextv ; exit with display
- ;--------------------------------------------------------------
- public _pcoutc
- _pcoutc:cmp byte ptr var0+1[di],0abh; initialized?
- jz pcoutc0 ; yes, branch
- jmp pcouti ; no, initialize
- ;
- pcoutc0:test usrflg,1 ; user input
- jnz pcoutcx ; yes, no go
- mov bl,var0[di] ; get channel
- mov bh,0 ; bx = channel
- add bx,offset dgroup:pcvc ; add table to offset
- mov al,[bx] ; get the value
- putn al ; send it out
- pcoutcx:nextv ; exit with display
- ;--------------------------------------------------------------
- public _pcoutd
- _pcoutd:cmp byte ptr var0+1[di],0abh; initialized?
- jz pcoutd0 ; yes, branch
- jmp pcouti ; no, initialize
- ;
- pcoutd0:test usrflg,1 ; user input
- jnz pcoutdx ; yes, no go
- mov bl,var0[di] ; get channel
- mov bh,0 ; bx = channel
- add bx,offset dgroup:pcvd ; add table to offset
- mov al,[bx] ; get the value
- putn al ; send it out
- pcoutdx:nextv ; exit with display
- ;--------------------------------------------------------------
- public _pcoute
- _pcoute:cmp byte ptr var0+1[di],0abh; initialized?
- jz pcoute0 ; yes, branch
- jmp pcouti ; no, initialize
- ;
- pcoute0:test usrflg,1 ; user input
- jnz pcoutex ; yes, no go
- mov bl,var0[di] ; get channel
- mov bh,0 ; bx = channel
- add bx,offset dgroup:pcve ; add table to offset
- mov al,[bx] ; get the value
- putn al ; send it out
- pcoutex:nextv ; exit with display
- ;--------------------------------------------------------------
- public _pcoutf
- _pcoutf:cmp byte ptr var0+1[di],0abh; initialized?
- jz pcoutf0 ; yes, branch
- jmp pcouti ; no, initialize
- ;
- pcoutf0:test usrflg,1 ; user input
- jnz pcoutfx ; yes, no go
- mov bl,var0[di] ; get channel
- mov bh,0 ; bx = channel
- add bx,offset dgroup:pcvf ; add table to offset
- mov al,[bx] ; get the value
- putn al ; send it out
- pcoutfx:nextv ; exit with display
- ;--------------------------------------------------------------
- public _pcoutg
- _pcoutg:cmp byte ptr var0+1[di],0abh; initialized?
- jz pcoutg0 ; yes, branch
- jmp pcouti ; no, initialize
- ;
- pcoutg0:test usrflg,1 ; user input
- jnz pcoutgx ; yes, no go
- mov bl,var0[di] ; get channel
- mov bh,0 ; bx = channel
- add bx,offset dgroup:pcvg ; add table to offset
- mov al,[bx] ; get the value
- putn al ; send it out
- pcoutgx:nextv ; exit with display
- ;--------------------------------------------------------------
- public _pcouth
- _pcouth:cmp byte ptr var0+1[di],0abh; initialized?
- jz pcouth0 ; yes, branch
- jmp pcouti ; no, initialize
- ;
- pcouth0:test usrflg,1 ; user input
- jnz pcouthx ; yes, no go
- mov bl,var0[di] ; get channel
- mov bh,0 ; bx = channel
- add bx,offset dgroup:pcvh ; add table to offset
- mov al,[bx] ; get the value
- putn al ; send it out
- pcouthx:nextv ; exit with display
- ;--------------------------------------------------------------
- public _pcoutx
- _pcoutx:cmp byte ptr var0+1[di],0abh; initialized?
- jz pcoutx0 ; yes, branch
- jmp pcouti ; no, initialize
- ;
- pcoutx0:test usrflg,1 ; user input
- jnz pcoutxx ; yes, no go
- mov bl,var0[di] ; get channel
- mov bh,0 ; bx = channel
- add bx,offset dgroup:pcvx ; add table to offset
- mov al,[bx] ; get the value
- putn al ; send it out
- pcoutxx:nextv ; exit with display
- ;--------------------------------------------------------------
- public _pcouty
- _pcouty:cmp byte ptr var0+1[di],0abh; initialized?
- jz pcouty0 ; yes, branch
- jmp pcouti ; no, initialize
- ;
- pcouty0:test usrflg,1 ; user input
- jnz pcoutyx ; yes, no go
- mov bl,var0[di] ; get channel
- mov bh,0 ; bx = channel
- add bx,offset dgroup:pcvy ; add table to offset
- mov al,[bx] ; get the value
- putn al ; send it out
- pcoutyx:nextv ; exit with display
- ;--------------------------------------------------------------
- public _pcoutz
- _pcoutz:cmp byte ptr var0+1[di],0abh; initialized?
- jz pcoutz0 ; yes, branch
- jmp pcouti ; no, initialize
- ;
- pcoutz0:test usrflg,1 ; user input
- jnz pcoutzx ; yes, no go
- mov bl,var0[di] ; get channel
- mov bh,0 ; bx = channel
- add bx,offset dgroup:pcvz ; add table to offset
- mov al,[bx] ; get the value
- putn al ; send it out
- pcoutzx:nextv ; exit with display
- ;--------------------------------------------------------------
- ; magenta input
- ;
- public upcout
- upcout: pop ax ; stack bullshit
- mov cmdflg,10 ; set up special routine
- mov special,offset upcoutx
- mov di,varsav ; point to variable list
- mov al,outn[di] ; get the output value
- mov var0[di],al ; save
- jmp workx ; on to the next stage
-
- upcoutx:mov di,varsav ; point to variable list
- mov al,outn[di] ; get the new channel
- xchg var0[di],al ; set it, get orig patch
- mov outn[di],al ; restore
- jmp _cancel ; exit
- ;==============================================================
- ; add switch
- ; inputs: 0: switch bits
- ; 1-8: switch inputs
- ; output: sequencer send to the controller
- ;--------------------------------------------------------------
- public _addswa
- _addswa:getv dl,var0 ; get the bits byte
- gettag ; es:bx = screen addr of tag
- dec bx ; drop back 1 for led
- add bx,640 ; bx = screen addr of 1st stage led
- mov bp,bx ; bp = leds
- add di,var1 ; point to first stage
- ;
- mov ah,1 ; set bit flag
- mov al,0 ; clear the add register
- mov cx,8 ; 8 to do
- addswa1:
- test dl,ah ; is the bit hi?
- jz addswa3 ; no, turn it off
- mov byte ptr es:[bp],red+hi ; else turn the led on
- mov bx,[di] ; get the value addr
- add al,[bx] ; add in the value
- jmp short addswa4 ; branch
- addswa3:
- mov byte ptr es:[bp],yellow ; turn the led off
- addswa4:
- add di,2 ; point to next val
- shl ah,1 ; bump bit pointer
- add bp,160 ; point to next led
- loop addswa1 ; do it again
- ;
- mov di,2[si] ; set di pointing to variable list
- putn al ; send it out
- addswax:nextv ; exit with display
- ;==============================================================
- ; Programmer add switch output values
- ; inputs: 0-3: switch inputs
- ; 4: control byte
- ; output: sequencer send to the controller
- ;--------------------------------------------------------------
- public _psouta
- _psouta:getv dl,var4 ; get the value
- mov cl,4 ; get shift
- shr dl,cl ; shift down
- and dl,15 ; mask
- ;
- gettag ; es:bx = screen addr of tag
- dec bx ; drop back 1 for led
- add bx,480 ; bx = screen addr of 1st stage led
- mov bp,bx ; bp = leds
- add di,var0 ; point to first stage
- ;
- mov ah,1 ; set bit flag
- mov al,0 ; clear the add register
- mov cx,4 ; 4 to do
- psouta1:
- test dl,ah ; is the bit hi?
- jz psouta3 ; no, turn it off
- mov byte ptr es:[bp],red+hi ; else turn the led on
- mov bx,[di] ; get the value addr
- add al,[bx] ; add in the value
- jmp short psouta4 ; branch
- psouta3:
- mov byte ptr es:[bp],yellow ; turn the led off
- psouta4:
- add di,2 ; point to next val
- shl ah,1 ; bump bit pointer
- add bp,160 ; point to next led
- loop psouta1 ; do it again
- ;
- mov di,2[si] ; set di pointing to variable list
- putn al ; send it out
- psoutax:nextv ; exit with display
- ;--------------------------------------------------------------
- public _psoutc
- _psoutc:getv dl,var4 ; get the value
- mov cl,4 ; get shift
- shr dl,cl ; shift down
- and dl,15 ; mask
- ;
- gettag ; es:bx = screen addr of tag
- dec bx ; drop back 1 for led
- add bx,480 ; bx = screen addr of 1st stage led
- mov bp,bx ; bp = leds
- add di,var0 ; point to first stage
- ;
- mov ah,1 ; set bit flag
- mov al,0 ; clear the add register
- mov cx,4 ; 4 to do
- psoutc1:
- test dl,ah ; is the bit hi?
- jz psoutc3 ; no, turn it off
- mov byte ptr es:[bp],red+hi ; else turn the led on
- mov bx,[di] ; get the value addr
- add al,[bx] ; add in the value
- jmp short psoutc4 ; branch
- psoutc3:
- mov byte ptr es:[bp],yellow ; turn the led off
- psoutc4:
- add di,2 ; point to next val
- shl ah,1 ; bump bit pointer
- add bp,160 ; point to next led
- loop psoutc1 ; do it again
- ;
- mov di,2[si] ; set di pointing to variable list
- putn al ; send it out
- psoutcx:nextv ; exit with display
- ;--------------------------------------------------------------
- public _psoutb
- _psoutb:getv dl,var4 ; get the value
- and dl,15 ; mask
- ;
- gettag ; es:bx = screen addr of tag
- dec bx ; drop back 1 for led
- add bx,480 ; bx = screen addr of 1st stage led
- mov bp,bx ; bp = leds
- add di,var0 ; point to first stage
- ;
- mov ah,1 ; set bit flag
- mov al,0 ; clear the add register
- mov cx,4 ; 4 to do
- psoutb1:
- test dl,ah ; is the bit hi?
- jz psoutb3 ; no, turn it off
- mov byte ptr es:[bp],red+hi ; else turn the led on
- mov bx,[di] ; get the value addr
- add al,[bx] ; add in the value
- jmp short psoutb4 ; branch
- psoutb3:
- mov byte ptr es:[bp],yellow ; turn the led off
- psoutb4:
- add di,2 ; point to next val
- shl ah,1 ; bump bit pointer
- add bp,160 ; point to next led
- loop psoutb1 ; do it again
- ;
- mov di,2[si] ; set di pointing to variable list
- putn al ; send it out
- psoutbx:nextv ; exit with display
- ;--------------------------------------------------------------
- public _psoutd
- _psoutd:getv dl,var4 ; get the value
- and dl,15 ; mask
- ;
- gettag ; es:bx = screen addr of tag
- dec bx ; drop back 1 for led
- add bx,480 ; bx = screen addr of 1st stage led
- mov bp,bx ; bp = leds
- add di,var0 ; point to first stage
- ;
- mov ah,1 ; set bit flag
- mov al,0 ; clear the add register
- mov cx,4 ; 4 to do
- psoutd1:
- test dl,ah ; is the bit hi?
- jz psoutd3 ; no, turn it off
- mov byte ptr es:[bp],red+hi ; else turn the led on
- mov bx,[di] ; get the value addr
- add al,[bx] ; add in the value
- jmp short psoutd4 ; branch
- psoutd3:
- mov byte ptr es:[bp],yellow ; turn the led off
- psoutd4:
- add di,2 ; point to next val
- shl ah,1 ; bump bit pointer
- add bp,160 ; point to next led
- loop psoutd1 ; do it again
- ;
- mov di,2[si] ; set di pointing to variable list
- putn al ; send it out
- psoutdx:nextv ; exit with display
- ;==============================================================
- ; Programmer add switch output values
- ; inputs: 0-3: switch inputs
- ; 4: control byte 5: shift
- ; output: sequencer send to the controller
- ;--------------------------------------------------------------
- public _psoute
- _psoute:getv dl,var4 ; get the value
- getv cl,var5 ; get shift
- shr dl,cl ; shift down
- and dl,15 ; mask
- ;
- gettag ; es:bx = screen addr of tag
- dec bx ; drop back 1 for led
- add bx,480 ; bx = screen addr of 1st stage led
- mov bp,bx ; bp = leds
- add di,var0 ; point to first stage
- ;
- mov ah,1 ; set bit flag
- mov al,0 ; clear the add register
- mov cx,4 ; 4 to do
- psoute1:
- test dl,ah ; is the bit hi?
- jz psoute3 ; no, turn it off
- mov byte ptr es:[bp],red+hi ; else turn the led on
- mov bx,[di] ; get the value addr
- add al,[bx] ; add in the value
- jmp short psoute4 ; branch
- psoute3:
- mov byte ptr es:[bp],yellow ; turn the led off
- psoute4:
- add di,2 ; point to next val
- shl ah,1 ; bump bit pointer
- add bp,160 ; point to next led
- loop psoute1 ; do it again
- ;
- mov di,2[si] ; set di pointing to variable list
- putn al ; send it out
- psoutex:nextv ; exit with display
- ;--------------------------------------------------------------
- public _psoutf
- _psoutf:getv dl,var4 ; get the value
- getv cl,var5 ; get shift
- shr dl,cl ; shift down
- and dl,15 ; mask
- ;
- gettag ; es:bx = screen addr of tag
- dec bx ; drop back 1 for led
- add bx,480 ; bx = screen addr of 1st stage led
- mov bp,bx ; bp = leds
- add di,var0 ; point to first stage
- ;
- mov ah,1 ; set bit flag
- mov al,0 ; clear the add register
- mov cx,4 ; 4 to do
- psoutf1:
- test dl,ah ; is the bit hi?
- jz psoutf3 ; no, turn it off
- mov byte ptr es:[bp],red+hi ; else turn the led on
- mov bx,[di] ; get the value addr
- add al,[bx] ; add in the value
- jmp short psoutf4 ; branch
- psoutf3:
- mov byte ptr es:[bp],yellow ; turn the led off
- psoutf4:
- add di,2 ; point to next val
- shl ah,1 ; bump bit pointer
- add bp,160 ; point to next led
- loop psoutf1 ; do it again
- ;
- mov di,2[si] ; set di pointing to variable list
- putn al ; send it out
- psoutfx:nextv ; exit with display
- ;==============================================================
- ; MIDI sys excl send (8 bytes max)
- ; inputs: 0: trigger, 1-8 input values to send, 9x: clock tick
- ; output: none
- ;--------------------------------------------------------------
- public _sysxo
- _sysxo:
- tick var0,var9 ;
- jnc sysxox ; exit if no tick
- mov al,0F0H ; send sys ex opcode
- call allmidi ; send to midi
- mov cx,8 ; 8 data bytes
- sysxo1: getv al,var1 ; get byte
- test al,80H ; don't send if ms bit is hi
- jnz sysxo2 ; /
- call allmidi ; else dump to midi
- sysxo2: add di,2 ; bump pointer
- loop sysxo1 ; do them all
- mov al,0F7H ; send eox
- call allmidi ; /
- sysxox: nextx ; exit
- ;==============================================================
- ; MIDI Control change
- ; inputs: 0: clock, 1: channel, 2: Control number, 3: Control value
- ; 4x: clock tick
- ; output: none
- ;--------------------------------------------------------------
- public _ctrlo
- _ctrlo:
- tick var0,var4 ; clock tick
- jnc ctrlox ; exit if no tick
- getv al,var1 ; get channel
- mchan al ; strip & set
- or al,0B0H ; MIDI Control Change
- call tomidi ; send it to midi
- getv al,var2 ; get control number
- and al,127 ; /
- call tomidi ; send data to midi
- getv al,var3 ; get control value
- and al,127 ; /
- call tomidi ; send data to midi
- ctrlox: nextx
- ;==============================================================
- ; MIDI Control mapping
- ; first group of control modules
- ;--------------------------------------------------------------
-
- public _mapo
- _mapo: test usrflg,1 ; inputting now
- jnz mapox ; yes, exit
- ;
- mov bp,si ; save si
- mov si,6[di] ; set up for show
- mov es,4[di] ; /
- mov bx,offset dgroup:ctrlmap; point to control map
- add si,320 ; point to 1st value screen location
- add di,var0 ; point to 1st value in module
- mov cx,8 ; # of values
- ;
- mapo1: mov al,[bx] ; look at value
- cmp al,[di] ; same as in module?
- jz mapo1a ; yes, branch
- mov [di],al ; no, make same
- tohex al ; display
- mov es:[si],ah ; /
- mov es:2[si],al ; /
- mapo1a: inc bx ; next map number
- add di,2 ; next value location
- add si,160 ; next screen location
- loop mapo1 ; do another
- ;
- mov si,bp ; restore si
- mapox: nextx ; exit
- ;--------------------------------------------------------------
- public umapo
- umapo: pop ax ; stack bullshit
- mov cmdflg,10 ; set up special routine
- mov special,offset umapox
- jmp workx ; on to the next stage
-
- umapox:
- mov bx,holdv ; get offset to the value
- mov di,varsav ; get value table for module
- mov dl,10[bx+di] ; get current value
- shr bx,1 ; /2 for byte table
- dec bx ; 1->n --> 0->n-1
- mov di,offset dgroup:ctrlmap; point to control map
- mov [di+bx],dl ; set new ctrl code
- jmp _cancel
- ;==============================================================
- ; MIDI Control mapping
- ; second group of control modules
- ;--------------------------------------------------------------
-
- public _mapp
- _mapp: test usrflg,1 ; inputting now
- jnz mappx ; yes, exit
- ;
- mov bp,si ; save si
- mov si,6[di] ; set up for show
- mov es,4[di] ; /
- mov bx,offset dgroup:ctrlmpp; point to control map
- add si,320 ; point to 1st value screen location
- add di,var0 ; point to 1st value in module
- mov cx,8 ; # of values
- ;
- mapp1: mov al,[bx] ; look at value
- cmp al,[di] ; same as in module?
- jz mapp1a ; yes, branch
- mov [di],al ; no, make same
- tohex al ; display
- mov es:[si],ah ; /
- mov es:2[si],al ; /
- mapp1a: inc bx ; next map number
- add di,2 ; next value location
- add si,160 ; next screen location
- loop mapp1 ; do another
- ;
- mov si,bp ; restore si
- mappx: nextx ; exit
- ;--------------------------------------------------------------
- public umapp
- umapp: pop ax ; stack bullshit
- mov cmdflg,10 ; set up special routine
- mov special,offset umappx
- jmp workx ; on to the next stage
-
- umappx:
- mov bx,holdv ; get offset to the value
- mov di,varsav ; get value table for module
- mov dl,10[bx+di] ; get current value
- shr bx,1 ; /2 for byte table
- dec bx ; 1->n --> 0->n-1
- mov di,offset dgroup:ctrlmpp; point to control map
- mov [di+bx],dl ; set new ctrl code
- jmp _cancel
- ;==============================================================
- ; MIDI note out.
- ; All parameters except Velocity are sent when changed.
- ; Velocity changes are ignored except zero transitions.
- ; When Velocity = 0, a Key-off message is sent with the currently
- ; saved note; the first NZ Velocity seen will send a Key-on message
- ; with the note value at the input, which gets saved, and the given
- ; velocity level. While Velocity stays NZ, any change in note values
- ; will cause an immediate Key-off message with the old note, then a
- ; Key on message with the new note, and the latest Velocity value for
- ; that note.
- ;--------------------------------------------------------------
- ; inputs:
- ; 0: Channel
- ; 1: Hold
- ; 2: Hold AND
- ; 3: Transpose
- ; 4: Transpose
- ; 5: Velocity Offset
- ; 6: Release Value
- ; 7, 9,11,13: Note value
- ; 8, 10,12,14: Velocity
- ; ---------------------
- ; 15x,16x,17x,18x: saved note
- ; 15+,16+,17+,18+: velocity tick flags
- ; ---------------------
- ; outn+1: b7 = initialized flag
- ; ---------------------
- ; temp0: transpose offset
- ; temp1: velocity offset
- ; temp2: release value
- ; temp3: enable flag
- ; ---------------------
- ; dh: channel
- ;--------------------------------------------------------------
- public _noteo,_noteo1,_noteo2,_noteo3
- _noteo3:nop
- _noteo2:nop
- _noteo1:nop
- _noteo:
- test byte ptr outn+1[di],80h ; initialized?
- jnz noteo1 ; yes, branch
- ;--------------------------------------------------------------
- ; initialize
- ;--------------------------------------------------------------
- mov cx,8 ; 4 note+velocity inputs
- mov bx,0 ; use for index
- noteo0: mov byte ptr var15[bp+di],0 ; clear
- inc bx ; bump index
- loop noteo0 ; loop
- initv var2,0ffh ; Hold mask <- FF
- mov byte ptr outn+1[di],80h ; set init flag
- nextx ; ... on to next module
- ;--------------------------------------------------------------
- ; Get Channel Number
- ;--------------------------------------------------------------
- noteo1: getv dh,var0 ; get it
- mchan dh ; mask & set
- xchg outn[di],dh ; save for next time
- cmp outn[di],dh ; same as last?
- jnz noteo2a ; no, mute with old
- ;--------------------------------------------------------------
- ; Check for Enable/Mute
- ;--------------------------------------------------------------
- mov temp3,0 ; zip enable flag
- getv al,var1 ; get enable
- getv ah,var2 ; get enable mask
- and al,ah ; /
- jz noteo2a ; mute if not enabled
- mov al,mprstf ; stop set
- or al,lodflg ; or load flag
- jz noteo2x ; branch if no mute
- noteo2a:mov temp3,1 ; else set it
- noteo2x:mov es,4[di] ; get seg addr
- mov bx,6[di] ; get module screen address
- dec bx ; point to led
- test temp3,1 ; test for z
- mov al,red ; set up for z
- jnz noteo2b ; branch if z
- mov al,red+hi ; else set up for nz
- noteo2b:mov es:[bx],al ; set the led
- ;--------------------------------------------------------------
- ; Get note Transpose value
- ;--------------------------------------------------------------
- getv al,var3 ; get it
- getv ah,var4 ; get it
- add al,ah ; add together
- mov temp0,al ; put it away
- ;--------------------------------------------------------------
- ; Get Velocity offset
- ;--------------------------------------------------------------
- getv al,var5 ; get it
- mov temp1,al ; put it away
- ;--------------------------------------------------------------
- ; Get Release value
- ;--------------------------------------------------------------
- getv al,var6 ; get it
- and al,127 ; strip msb
- mov temp2,al ; put it away
- ;--------------------------------------------------------------
- ; Key/velocity "A"
- ;--------------------------------------------------------------
- push si ; save si
- mov si,di ; use as saved value ptr
- add si,var15 ; si = onv, si+1 = vflag
- mov bp,4 ; do 4 of them
- ;
- noteo4: test temp3,1 ; mute?
- jnz noteo4a ; yes, branch
- ;
- getv ah,var8 ; get velocity
- or ah,ah ; is it on?
- jnz noteo4b ; yes, branch
- ;
- noteo4a:test byte ptr 1[si],1 ; was note on
- jz noteo4x ; no, exit
- ;
- mov al,[si] ; yes, turn old note off
- call noteoff ; /
- mov byte ptr 1[si],0 ; zip vflag
- jmp noteo4x ; exit
- ;
- noteo4b:test byte ptr 1[si],1 ; was note on
- jnz noteo4c ; yes, branch
- ;
- getv al,var7 ; get the note
- add al,temp0 ; add offset
- mov [si],al ; save it
- call noteon ; turn it on
- mov byte ptr 1[si],1 ; flag it
- jmp noteo4x ; exit
- ;
- noteo4c:getv al,var7 ; get the note
- add al,temp0 ; add offset
- cmp al,[si] ; has it changed?
- jz noteo4x ; no, exit
- ;
- xchg al,[si] ; yes, swap new w old
- call noteoff ; turn old off
- mov al,[si] ; turn new on
- call noteon
- ;
- noteo4x:
- add si,2 ; bump pointers
- add di,4 ; /
- dec bp ; dec loop index
- jnz noteo4 ; loop
- pop si ; restore si
- nextx
- ;--------------------------------------------------------------
- ; Note On
- ; call nv in al, v in ah
- ;--------------------------------------------------------------
- Noteon:
- xchg al,dh ; get channel
- or al,090H ; MIDI Key-on
- call tomidi ; send Key-on+channel
- xchg al,dh ; get nv, restore channel
- and al,127 ; strip msb
- call tomidi ; send Note value
- mov al,ah ; get velocity
- add al,temp1 ; add offset
- jns noteon1 ; branch if < 128
- mov al,127 ; else make 127
- noteon1:call tomidi ; send Velocity
- ret ; exit
- ;--------------------------------------------------------------
- ; Note Off
- ; call nv in al
- ;--------------------------------------------------------------
- Noteoff:
- xchg al,dh ; get channel
- or al,080H ; MIDI Key-off
- call tomidi ; send Key-off+channel
- xchg al,dh ; get nv, restore channel
- and al,127 ; strip msb
- call tomidi ; send Note value
- mov al,temp2 ; get release value
- call tomidi ; send release value
- ret ; exit
- ;==============================================================
- ; MIDI channel output controller
- ;--------------------------------------------------------------
- ; inputs:
- ; 0: channel
- ; 1: Hold
- ; 2: Program change
- ; 3: After Touch
- ; 4: Pitch Bend
- ; ---------------------
- ; 5: Volume (mapo 0)
- ; 6: Mod whl (mapo 1)
- ; 7: controller A (mapo 2)
- ; 8: controller B (mapo 3)
- ; 9: controller C (mapo 4)
- ; 10:controller D (mapo 5)
- ; 11:controller 1 (mapo 6)
- ; 12:controller 2 (mapo 7)
- ; ---------------------
- ; 13x: old program change
- ; 13+: old after touch
- ; 14x: old pitch bend
- ; 15x - 18+: old controller values
- ; ---------------------
- ; outn+1: b7 = initialized flag
- ; ---------------------
- ; dh: channel
- ;--------------------------------------------------------------
- public _chano,_chanl
- _chanl: mov bp,offset dgroup:ctrlmpp; index for ctrlmap
- jmp chanl0 ; start w 2nd map
- ;--------------------------------------------------------------
- _chano: mov bp,offset dgroup:ctrlmap; index for ctrlmap
- chanl0: test byte ptr outn+1[di],80h ; initialized?
- jnz chano1 ; yes, branch
- ;--------------------------------------------------------------
- ; initialize
- ;--------------------------------------------------------------
- initv var1,1 ; Hold <- 1
- initv var4,080h ; Bend <- 80H
- initv var5,07fh ; Volume <- 7fH
- mov byte ptr outn+1[di],80h ; set init flag
- ;
- chano0: mov cx,12 ; 12 save areas
- mov bx,0 ; use for index
- chano0a:mov byte ptr var13[bx+di],-1; set to force change
- inc bx ; bump index
- loop chano0a ; loop
- or clrchf,2 ; setup to clear
- chano0x:
- nextx ; ... on to next module
- ;--------------------------------------------------------------
- ; Get Channel Number
- ;--------------------------------------------------------------
- chano1:
- getv dh,var0 ; get it
- mchan dh ; mask & set
- test valflg,-1 ; inputting values?
- jnz chano1a ; yes, branch out
- xchg outn[di],dh ; save for next time
- cmp outn[di],dh ; same as last?
- jnz chano0 ; no, force change
- chano1a:
- ;--------------------------------------------------------------
- ; Check for Hold
- ;--------------------------------------------------------------
- getv al,var1 ; get hold
- or al,mprstf ; or program reset
- or al,lodflg ; or load flag
- or al,clrchf ; clear chan flag?
- jnz chano1b ; yes, force change
- mov al,0 ; clear led flag
- ;--------------------------------------------------------------
- chano1b:mov es,4[di] ; get seg addr
- mov bx,6[di] ; get module screen address
- dec bx ; point to led
- test al,-1 ; test for z
- jz chano1c ; branch if z
- mov byte ptr es:[bx],red ; clr the led
- jmp chano0 ; reset stuff
- chano1c:mov byte ptr es:[bx],red+hi ; set the led
- ;--------------------------------------------------------------
- ; Patch Change
- ;--------------------------------------------------------------
- getv al,var2 ; get input value
- cmp al,var13[di] ; any change
- jz chano2x ; no, branch
- and al,7fh ; mask
- mov var13[di],al ; yes, store the new value
- mov ah,0C0H ; MIDI Patch Change
- or ah,dh ; add in channel info
- xchg al,ah ; fix
- call tomidi ; send it to midi
- xchg al,ah ; fix
- call tomidi ; send value to midi
- chano2x:
- ;--------------------------------------------------------------
- ; Aftertouch
- ;--------------------------------------------------------------
- getv al,var3 ; get input value
- cmp al,var13+1[di] ; any change
- jz chano3x ; no, branch
- and al,127 ; strip msb
- mov var13+1[di],al ; yes, store the new value
- mov ah,0D0H ; MIDI After Touch
- or ah,dh ; add in channel info
- xchg al,ah ; fix
- call tomidi ; send it to midi
- xchg al,ah ; fix
- call tomidi ; send value to midi
- chano3x:
- ;--------------------------------------------------------------
- ; Pitch Bend
- ;--------------------------------------------------------------
- getv al,var4 ; get input value
- cmp al,var14[di] ; any change
- jz chano5x ; no, branch
- mov var14[di],al ; yes, store the new value
- ; add al,80h ; center for pitch bend
- shr al,1 ; strip lsb
- rcr ch,1 ; put in ch
- rcr ch,1 ; mov into position
- and ch,64 ; clean it up
- mov ah,0E0H ; MIDI Pitch Bend
- or ah,dh ; add in channel info
- xchg ah,al ; fix
- call tomidi ; send it to midi
- mov al,ch ; fix
- call tomidi ; send ls value to midi
- mov al,ah ; fix
- call tomidi ; send ms value to midi
- chano5x:
- ;--------------------------------------------------------------
- ; Controllers mapped by mapo module into array: ctrlmap 0-5
- ;--------------------------------------------------------------
- push si ; save si
- mov si,di ; use as pointer
- add si,var15 ; /
- mov cx,6 ; 6 to do
- chano6:
- getv al,var5 ; get input value
- cmp al,[si] ; any change
- jz chano6a ; no, branch
- and al,127 ; strip msb
- mov [si],al ; yes, store the new value
- mov ah,0B0H ; MIDI Control Change
- or ah,dh ; add in channel info
- xchg ah,al ; fix
- call tomidi ; send it to midi
- mov al,ds:[bp] ; mapped ctrl number
- call tomidi ; send it to midi
- xchg ah,al ; fix
- call tomidi ; send value to midi
- chano6a:inc bp ; bump pointers
- inc si ; /
- add di,2 ; /
- loop chano6 ; loop
- ;--------------------------------------------------------------
- ; Controllers mapped by mapo module into array: ctrlmap 6,7
- ;--------------------------------------------------------------
- mov cx,2 ; 2 to do
- chano7:
- getv al,var5 ; get input value
- and al,127 ; strip msb, test for Z
- jz chano7b ; branch if Z
- mov al,127 ; else make 127
- chano7b:cmp al,[si] ; any change
- jz chano7a ; no, branch
- mov [si],al ; yes, store the new value
- mov ah,0B0H ; MIDI Control Change
- or ah,dh ; add in channel info
- xchg ah,al ; fix
- call tomidi ; send it to midi
- mov al,ds:[bp] ; mapped ctrl number
- call tomidi ; send it to midi
- xchg ah,al ; fix
- call tomidi ; send value to midi
- chano7a:inc bp ; bump pointers
- inc si ; /
- add di,2 ; /
- loop chano7 ; loop
- ;
- pop si ; restore si
- nextx ; exit
- ;==============================================================
- ; MIDI event programmer/sequencer
- ; normal output, all inputs are magenta user inputs.
- ; -- all number inputs use addr+1 to hold output flag copy
- ; inputs:
- ; 0x: user input to change address
- ; 1x: end address
- ; 2x: Undo switch
- ; 2+: user input flag
- ; 3x: Store switch
- ; 3+: initialized flag
- ; 4x: Recall switch
- ; 4+: module number
- ; 5x: Save switch
- ; 6x: Measures to next (first of sequencer data)
- ; 7x: stage 1
- ; 8x: stage 2
- ; 9x: stage 3
- ; 10x: stage A
- ; 11x: stage B
- ; 12x: stage C
- ; 13x: stage D
- ; 14x: stage w slew E
- ; 15x: slew value for E
- ; 16x: stage w slew F
- ; 17x: slew value for F
- ; 18x: stage w slew G
- ; 19x: slew value for G
- ; 20x: stage w slew H
- ; 21x: slew value for H
- ; slewc: slew value buffer C
- ; slewd: slew value buffer D
- ; slewe: slew value buffer E
- ; slewf: slew value buffer F
- ; pubuf: Undo Buffer
- ; psbuf: Save Buffer
- ;--------------------------------------------------------------
- public _progo
- _progo: cmp byte ptr var3+1[di],0abh; initialized?
- jz progoii ; yes, branch
- ;
- mov cx,98 ; big mother
- mov bx,var0 ; clear variable space
- progoi: mov byte ptr [bx+di],0 ; zip it
- inc bx ; bump address
- loop progoi ; loop
- ;
- mov al,modnum ; get module number
- mov byte ptr var4+1[di],al ; save it
- mov byte ptr var3+1[di],0abh; set init flag
- ;
- progoii:test usrflg,1 ; user input now?
- jz progo0 ; no, branch
- mov byte ptr var2+1[di],1 ; yes, set show differences
- nextx ; ...easy exit
- ;--------------------------------------------------------------
- ; process master reset
- ;
- progo0: mov al,mpadrf ; address change?
- or al,al ; /
- jz progo0a ; no, branch
- mov al,mpadr ; yes, get master address
- mov var0[di],al ; set local address = master
- progo0a:
- ;--------------------------------------------------------------
- mov bp,si ; save si
- mov es,4[di] ; get screen seg addr
- mov si,6[di] ; get screen ofst addr
- ;--------------------------------------------------------------
- test mpmodf,1 ; programming or playing?
- jz progo1 ; branch if playing
- jmp progo2 ; else jump to programming
- ;--------------------------------------------------------------
- ; mode = playing
- ;--------------------------------------------------------------
- ;
- progo1: test mmstart,1 ; master measure start?
- jz progo1b ; no, branch
- cmp byte ptr var6[di],0 ; local measure count = 0?
- jz progo1a ; yes, branch
- dec byte ptr var6[di] ; no, count down 1
- jmp short progo1b ; ...on to the next
- ;--------------------------------------------------------------
- ; address change
- ;
- progo1a:mov al,var1[di] ; is end <= address
- cmp al,byte ptr var0[di] ; /
- jbe progo1b ; yes, don't bump address
- test mprstf,-1 ; master reset?
- jnz progo1b ; yes, don't bump address
- inc byte ptr var0[di] ; else bump sequencer address
- progo1b:mov al,var0[di] ; has address changed
- cmp al,var0+1[di] ; /
- jz progo1c ; no, branch
- putn al ; yes, send it out
- call sq_ob ; yes copy seq to output buffer
- mov byte ptr var2+1[di],1 ; set show differences
- showpq 0 ; display address
- progo1c:showpq 6 ; display measure counter
- jmp progo3 ; branch to common stuff
- ;--------------------------------------------------------------
- ; mode = programming
- ;--------------------------------------------------------------
- ; address change
- ;
- progo2: mov al,var0[di] ; has address changed
- cmp al,var0+1[di] ; /
- jz progo2a ; no, branch
- putn al ; yes, send it out
- call ob_ub ; output buf to undo buf
- call sq_ob ; sequencer to output buf
- showpq 0 ; display the new value
- mov byte ptr var2+1[di],1 ; set show differences
- progo2a:
- ;--------------------------------------------------------------
- ; measures counter
- ;
- mov al,var6[di] ; measures value changed?
- cmp al,var6+1[di] ; /
- jz progo2e ; no, branch
- mov var6+1[di],al ; yes, clear flag
- showpv 6 ; display measure counter
- mov byte ptr var2+1[di],1 ; set show differences
- progo2e:
- ;--------------------------------------------------------------
- ; undo button
- ;
- test byte ptr var2[di],1 ; undo button pushed?
- jz progo2b ; no, branch
- mov byte ptr var2[di],0 ; clear the button
- call ub_ob ; swap undo with output
- jmp short progo2z ; show & tell
- progo2b:
- ;--------------------------------------------------------------
- ; store button
- ;
- test byte ptr var3[di],1 ; store button pushed?
- jz progo2c ; no, branch
- mov byte ptr var3[di],0 ; clear the button
- call sq_ub ; sequencer to undo buf
- call ob_sq ; output buffer to seq
- ; or _mpab,2 ; set buffer used flag
- jmp short progo2z ; show & tell
- progo2c:
- ;--------------------------------------------------------------
- ; recall button
- ;
- test byte ptr var4[di],1 ; recall button pushed?
- jz progo2d ; no, branch
- mov byte ptr var4[di],0 ; clear the button
- call ob_ub ; output buf to undo buf
- call sb_ob ; save buf to out buf
- jmp short progo2z ; show & tell
- progo2d:
- ;--------------------------------------------------------------
- ; save button
- ;
- test byte ptr var5[di],1 ; save button pushed?
- jz progo2x ; no, branch
- mov byte ptr var5[di],0 ; clear the button
- call ob_sb ; output buf to save buf
- ;--------------------------------------------------------------
- progo2z:mov byte ptr var2+1[di],1 ; set show differences
- progo2x:
- ;--------------------------------------------------------------
- ; common code for programming or playing
- ;--------------------------------------------------------------
- ; process outbyte
- ;
- progo3:
- mov al,var7[di] ; out byte change?
- cmp al,var7+1[di] ; /
- jz progo3a ; no, jmp to next
- mov var7+1[di],al ; yes, set flag
- mov bl,var4+1[di] ; bx = Channel
- mov bh,0 ; /
- add bx,offset dgroup:pcvx ; point to outval table
- mov [bx],al ; put value to the table
- progo3a:showpv 7 ; update display
- ;--------------------------------------------------------------
- mov al,var8[di] ; out byte change?
- cmp al,var8+1[di] ; /
- jz progo3b ; no, jmp to next
- mov var8+1[di],al ; yes, set flag
- mov bl,var4+1[di] ; bx = Channel
- mov bh,0 ; /
- add bx,offset dgroup:pcvy ; point to outval table
- mov [bx],al ; put value to the table
- progo3b:showpv 8 ; update display
- ;--------------------------------------------------------------
- mov al,var9[di] ; out byte change?
- cmp al,var9+1[di] ; /
- jz progo3c ; no, jmp to next
- mov var9+1[di],al ; yes, set flag
- mov bl,var4+1[di] ; bx = Channel
- mov bh,0 ; /
- add bx,offset dgroup:pcvz ; point to outval table
- mov [bx],al ; put value to the table
- progo3c:showpv 9 ; update display
- ;--------------------------------------------------------------
- ; send non-slew output values
- ;
- ;progo4:
- ;--------------------------------------------------------------
- mov al,var10[di] ; out byte change?
- cmp al,var10+1[di] ; /
- jz progo4a ; no, jmp to next
- mov var10+1[di],al ; yes, set flag
- mov bl,var4+1[di] ; bx = Channel
- mov bh,0 ; /
- add bx,offset dgroup:pcva ; point to outval table
- mov [bx],al ; put value to the table
- progo4a:showpv 10 ; update display
- ;--------------------------------------------------------------
- mov al,var11[di] ; out byte change?
- cmp al,var11+1[di] ; /
- jz progo4b ; no, jmp to next
- mov var11+1[di],al ; yes, set flag
- mov bl,var4+1[di] ; bx = Channel
- mov bh,0 ; /
- add bx,offset dgroup:pcvb ; point to outval table
- mov [bx],al ; put value to the table
- progo4b:showpv 11 ; update display
- ;--------------------------------------------------------------
- mov al,var12[di] ; out byte change?
- cmp al,var12+1[di] ; /
- jz progo4c ; no, jmp to next
- mov var12+1[di],al ; yes, set flag
- mov bl,var4+1[di] ; bx = Channel
- mov bh,0 ; /
- add bx,offset dgroup:pcvc ; point to outval table
- mov [bx],al ; put value to the table
- progo4c:showpv 12 ; update display
- ;--------------------------------------------------------------
- mov al,var13[di] ; out byte change?
- cmp al,var13+1[di] ; /
- jz progo4d ; no, jmp to next
- mov var13+1[di],al ; yes, set flag
- mov bl,var4+1[di] ; bx = Channel
- mov bh,0 ; /
- add bx,offset dgroup:pcvd ; point to outval table
- mov [bx],al ; put value to the table
- progo4d:showpv 13 ; update display
- ;--------------------------------------------------------------
- ; send values with slew
- ;
- mov bx,slewe ; point to slew buffer
- mov dx,var14[di] ; get input & target
- mov cl,var15[di] ; get rate
- call pslew ; get new slew value
- cmp var14[di],dx ; did it change?
- mov var14[di],dx ; (put it away)
- jz progo4e ; no change,split
- ;
- mov bl,var4+1[di] ; bx = Channel
- mov bh,0 ; /
- add bx,offset dgroup:pcve ; point to outval table
- mov [bx],dh ; put value to the table
- ;
- progo4e:showpp 14 ; update display
- showpq 15 ; display & flag rate
- ;--------------------------------------------------------------
- mov bx,slewf ; point to slew buffer
- mov dx,var16[di] ; get input & target
- mov cl,var17[di] ; get rate
- call pslew ; get new slew value
- cmp var16[di],dx ; did it change?
- mov var16[di],dx ; (put it away)
- jz progo4f ; no change,split
- ;
- mov bl,var4+1[di] ; bx = Channel
- mov bh,0 ; /
- add bx,offset dgroup:pcvf ; point to outval table
- mov [bx],dh ; put value to the table
- ;
- progo4f:showpp 16 ; update display
- showpq 17 ; display & flag rate
- ;--------------------------------------------------------------
- mov bx,slewg ; point to slew buffer
- mov dx,var18[di] ; get input & target
- mov cl,var19[di] ; get rate
- call pslew ; get new slew value
- cmp var18[di],dx ; did it change?
- mov var18[di],dx ; (put it away)
- jz progo4g ; no change,split
- ;
- mov bl,var4+1[di] ; bx = Channel
- mov bh,0 ; /
- add bx,offset dgroup:pcvg ; point to outval table
- mov [bx],dh ; put value to the table
- ;
- progo4g:showpp 18 ; update display
- showpq 19 ; display & flag rate
- ;--------------------------------------------------------------
- mov bx,slewh ; point to slew buffer
- mov dx,var20[di] ; get input & target
- mov cl,var21[di] ; get rate
- call pslew ; get new slew value
- cmp var20[di],dx ; did it change?
- mov var20[di],dx ; (put it away)
- jz progo4h ; no change,split
- ;
- mov bl,var4+1[di] ; bx = Channel
- mov bh,0 ; /
- add bx,offset dgroup:pcvh ; point to outval table
- mov [bx],dh ; put value to the table
- ;
- progo4h:showpp 20 ; update display
- showpq 21 ; display & flag rate
- ;--------------------------------------------------------------
- ; module execution ends here
- ; clean up & display output value
- ;--------------------------------------------------------------
- test byte ptr var2+1[di],1 ; show differences?
- jz progo6a ; no, branch
- call sq?ob ; show if ob <> seq
- progo6a:mov si,bp ; restore si
- mov byte ptr var2+1[di],0 ; clear user input flag
- nextv ; display output, exit
- ;--------------------------------------------------------------
- ; subroutine to update slew value
- ; call with bx = slew buffer offset (slewc, slewd, etc.)
- ; dx = input/output (dh), target (dl)
- ; cl = rate
- ; returns with dx = input/output, target
- ;
- ; formula:
- ; initialize:
- ; input * 256 --> sum; input --> output
- ; thereafter until sum/256 = target:
- ; sum - input + target --> sum
- ; sum/256 --> output
- ;
- ; buffer offsets for values:
- ; 0: sum
- ; 2: saved input
- ; 3: saved target
- ; 4: saved rate
- ; 5: busy
- ;--------------------------------------------------------------
- pslew: test byte ptr 5[bx+di],1 ; busy?
- jnz pslewa ; yes, branch
- cmp dl,dh ; no, see if target=output
- jnz pslewb ; not equal, go slew
- cmp dh,2[bx+di] ; else see if input has changed
- jz pslewx ; exit if no change
- ;
- pslewb: mov 3[bx+di],dl ; save target
- mov 2[bx+di],dh ; save input
- mov 4[bx+di],cl ; save rate
- ;
- mov dh,dl ; target --> output
- or cl,cl ; rate = 0?
- jz pslewx ; yes, just exit
- ; test mpmodf,1 ; programming or playing?
- ; jnz pslewx ; just exit if programming
- mov byte ptr 5[bx+di],1 ; else flag busy
- ;
- mov al,2[bx+di] ; ax = input * 128
- mov ah,0 ; /
- mov cl,7 ; /
- shl ax,cl ; /
- ; mov ah,2[bx+di] ; ax = input * 256
- ; mov al,0 ; /
- mov [bx+di],ax ; set new sum
- mov dh,2[bx+di] ; input --> output
- jmp short pslewx ; exit
- ;
- pslewa: dec byte ptr 4[bx+di] ; countdown
- jnz pslewx ; /
- or cl,cl ; rate set to 0?
- jnz pslewc ; no, go on
- mov dh,dl ; yes, set output=target
- jmp short pslewz ; exit finished
- ;
- pslewc: mov 4[bx+di],cl ; save rate count
- mov ax,[bx+di] ; ax = sum
- mov cl,2[bx+di] ; cx = input
- mov ch,0 ; /
- sub ax,cx ; ax = sum - input
- mov cl,3[bx+di] ; cx = target
- add ax,cx ; ax = sum - input + target
- mov [bx+di],ax ; save new sum
- mov cl,7 ; ax = new sum / 128
- ;
- shr ax,cl ; /
- mov dh,al ; dh = new sum / 128
- ; mov dh,ah ; dh = new sum / 256
- pslewz: cmp dh,dl ; output = target
- jnz pslewx ; no, exit
- mov byte ptr 5[bx+di],0 ; yes, flag not busy
- ;
- pslewx: ret ; exit
- ;--------------------------------------------------------------
- ; subroutines to copy sequencer buffers
- ;
- ; ob_sb = obuf --> sbuf = output buffer to save buffer
- ; ob_ub = obuf --> ubuf = output buffer to undo buffer
- ; ob_sq = obuf --> seq = output buffer to sequencer
- ; sb_ob = sbuf --> obuf = save buffer to output buffer
- ; sq_ob = seq --> obuf = sequencer to output buffer
- ; sq_ub = seq --> ubuf = sequencer to undo buffer
- ; ub_ob = ubuf <-> obuf = undo buffer swapped with output buffer
- ; sq?ob = show red if sq <> ob, else show yellow
- ;--------------------------------------------------------------
- ; ob_sb = obuf --> sbuf = output buffer to save buffer
- ;
- ob_sb: mov bx,di ; use bx for sbuf addr
- add bx,psbuf ; bx = sbuf addr
- jmp short ob_ub0 ; go do it
- ;--------------------------------------------------------------
- ; ob_ub = obuf --> ubuf = output buffer to undo buffer
- ;
- ob_ub: mov bx,di ; use bx for sbuf addr
- add bx,pubuf ; bx = ubuf addr
- ;
- ob_ub0: mov si,di ; get offset to obuf
- add si,var6 ; /
- ;
- mov cx,16 ; 16 in a loop
- ob_ubl: mov al,[si] ; get obuf byte
- mov [bx],al ; put it away
- inc bx ; bump pointers
- add si,2 ; /
- loop ob_ubl ; loop til done
- ;
- mov si,6[di] ; get screen ofst addr
- ret
- ;--------------------------------------------------------------
- ; ob_sq = obuf --> seq = output buffer to sequencer
- ;
- ob_sq: mov ah,var4+1[di] ; offset for channel
- mov al,0 ; /
- add ax, seg bufpa ; base seg of seq buffer
- mov es,ax ; es = seg addr of seq buf
- mov al,var0[di] ; get seq step
- mov bl,16 ; bump up
- mul bl ; ax = seq addr
- mov bx,ax ; es:bx = seq addr
- ;
- mov si,di ; get offset to obuf
- add si,var6 ; /
- ;
- mov cx,16 ; 16 in a loop
- ob_sql: mov al,[si] ; get buffer byte
- mov es:[bx],al ; put to sequencer
- inc bx ; bump pointers
- add si,2 ; /
- loop ob_sql ; loop til done
- ;
- mov es,4[di] ; restore screen seg addr
- mov si,6[di] ; get screen ofst addr
- ret
- ;--------------------------------------------------------------
- ; sb_ob = sbuf --> obuf = save buffer to output buffer
- ;
- sb_ob: mov bx,di ; use bx for sbuf addr
- add bx,psbuf ; bx = sbuf addr
-
- mov si,di ; get offset to obuf
- add si,var6 ; /
- ;
- mov cx,16 ; 16 in a loop
- sb_obl: mov al,[bx] ; get sbuf byte
- mov [si],al ; put to obuf
- inc bx ; bump pointers
- add si,2 ; /
- loop sb_obl ; loop til done
- ;
- mov si,6[di] ; get screen ofst addr
- ret
- ;--------------------------------------------------------------
- ; sq_ob = seq --> obuf = sequencer to output buffer
- ;
- sq_ob: mov ah,var4+1[di] ; offset for channel
- mov al,0 ; /
- add ax,seg bufpa ; base seg of seq buffer
- mov es,ax ; es = seg addr of seq buf
- mov al,var0[di] ; get seq step
- mov bl,16 ; bump up
- mul bl ; ax = seq addr
- mov bx,ax ; es:bx = seq addr
- ;
- mov si,di ; get offset to obuf
- add si,var6 ; /
- ;
- mov cx,16 ; 16 in a loop
- sq_obl: mov al,es:[bx] ; get the byte
- mov [si],al ; put it away
- inc bx ; bump pointers
- add si,2 ; /
- loop sq_obl ; loop til done
- ;
- mov es,4[di] ; restore screen seg addr
- mov si,6[di] ; get screen ofst addr
- ret
- ;--------------------------------------------------------------
- ; sq_ub = seq --> ubuf = sequencer to undo buffer
- ;
- sq_ub: mov ah,var4+1[di] ; offset for channel
- mov al,0 ; /
- add ax, seg bufpa ; base seg of seq buffer
- mov es,ax ; es = seg addr of seq buf
- mov al,var0[di] ; get seq step
- mov bl,16 ; bump up
- mul bl ; ax = seq addr
- mov bx,ax ; es:bx = seq addr
- ;
- mov si,di ; use si for sbuf addr
- add si,pubuf ; si = ubuf addr
- ;
- mov cx,16 ; 16 bytes to move
- sq_ubl: mov al,es:[bx] ; get seq byte
- mov [si],al ; put it in ubuf
- loop sq_ubl ; loop til done
- ;
- mov es,4[di] ; restore screen seg addr
- mov si,6[di] ; get screen ofst addr
- ret
- ;--------------------------------------------------------------
- ; ub_ob = ubuf <-> obuf = undo buffer swapped with output buffer
- ;
- ub_ob: mov bx,di ; use bx for sbuf addr
- add bx,pubuf ; bx = ubuf addr
- ;
- mov si,di ; get offset to obuf
- add si,var6 ; /
- ;
- mov cx,16 ; 16 in a loop
- ub_obl: mov al,[si] ; get obuf byte
- xchg [bx],al ; put it away
- mov [si],al ; swap
- inc bx ; bump pointers
- add si,2 ; /
- loop ub_obl ; loop til done
- ;
- mov si,6[di] ; get screen ofst addr
- ret
-
- ;--------------------------------------------------------------
- ; sq?ob show red for each of the 16 values when sq <> ob,
- ; else show yellow
- ;
- sq?ob: mov ah,var4+1[di] ; offset for channel
- mov al,0 ; /
- add ax, seg bufpa ; base seg of seq buffer
- mov es,ax ; es = seg addr of seq buf
- mov cx,ax ; cx = copy of above
- mov al,var0[di] ; get seq step
- mov bl,16 ; bump up
- mul bl ; ax = seq addr
- mov bx,ax ; es:bx = seq addr
- ;
- mov si,di ; get offset to obuf
- add si,var6 ; ds:si = offset to obuf
- ;
- push bp ; save current bp
- mov bp,ds:4[di] ; bp = screen seg
- mov dx,6[di] ; dx = screen address
- add dx,160*6+480 ; dx = offset to var6
- dec dx ; back up to point to label
- xchg dx,di ; di = offset to var6
- ; ; dx = old di (save)
- mov ah,16 ; 16 in a loop
- sq?obl: mov al,es:[bx] ; get the byte at var
- cmp [si],al ; same
- mov al,yellow ; pretend it is
- jz sq?ob2 ; yes, branch
- mov al,red
- sq?ob2: mov es,bp ; get screen seg
- mov es:[di],al ; set color
- mov es,cx ; seq seg
- inc bx ; bump pointers
- add si,2 ; /
- add di,160 ; /
- dec ah ; loop til done
- jnz sq?obl ; /
- ;
- pop bp ; restore bp
- mov di,dx ; restor variable indes
- mov es,4[di] ; restore screen seg addr
- mov si,6[di] ; get screen ofst addr
- ret
- ;--------------------------------------------------------------
- ; process magenta inputs
- ;
- public uprogo
- uprogo: pop ax ; stack bullshit
- mov di,varsav ; get value table for module
- cmp magflg,0 ; no-value?
- jnz uprogb ; no, branch
- mov bx,holdv ; get offset to the value
- xor byte ptr 10[bx+di],1 ; flip value of input
- uprogr: jmp _cancel ; exit
- ;
- uprogb: mov cmdflg,10 ; set up special routine
- mov special,offset uprogr ; data exit
- jmp workx ; on to the next stage
- ;==============================================================
- ; beep a note on the pc speaker
- ; inputs: 0: gate, 1: pitch, 2x: note flags
- ; output: gate
- ;--------------------------------------------------------------
- public _bopo
- _bopo:
- test mprstf,-1 ; stopped?
- jz bopogo ; no, go on
- call toneoff ; yes, turn off the speaker
- jmp bopox ; exit
-
- bopogo: getv al,var0 ; get the gate
- mov dl,var2[di] ; dl = on/off flags
- or al,al ; gate on?
- jz bopo1 ; no, branch
- and dl,offlg xor -1 ; yes, clear off flag
- test dl,onflg ; is on flag set?
- jz bopo2 ; no, branch
- bopo3:
- mov di,2[si] ;; set di pointing to variable list
- nextx ; yes, easy exit
- bopo2: or dl,onflg ; no, set on flag
- mov var2[di],dl ; put it away
- ;--------------------------------------------------------------
- ; note on
- getv al,var1 ; get the pitch
- call pitch ; play it
- mov cx,dx ; /
- call toneset ; /
- call toneon ; /
- mov ah,-1 ; load True
- putn ah ; flag to the output
- jmp short bopox
- ;--------------------------------------------------------------
- bopo1: and dl,onflg xor -1 ; clock is off, clear on flag
- test dl,offlg ; off flag set?
- jnz bopo3 ; yes, easy exit
- or dl,offlg ; no, set the off flag
- mov var2[di],dl ; put it away
- call toneoff ; turn off the note
- mov ah,0 ; load False
- putn ah ; flag to the output
- bopox:
- mov di,2[si] ;; set di pointing to variable list
- nextx ; exit
- ;--------------------------------------------------------------
- ; play tones on the pc speaker
- ;
- ;--------------------------------------------------------------
- ; initialize timer chip
- ; Just called once
- ;
- toneinit:
- ; mov al,2*40h+3*10h+3*2
- ; out 43h,al
- ret
- ;--------------------------------------------------------------
- ; convert from frequency to period
- ; input: frequency in CX
- ; output: period in CX
- ;
- freq: push dx
- push ax
- ;
- mov dx,12H
- mov ax,34deh
- div cx
- mov cx,ax
- ;
- pop ax
- pop dx
- ret
- ;--------------------------------------------------------------
- ; convert from a pitch to a number
- ; input: pitch number in al
- ; output: value for TONESET in DX
- ;--------------------------------------------------------------
- pitch: push cx
- push bx
- push ax
- ;
- mov ah,0
- mov cl,12
- div cl
- ;
- mov dl,al
- mov al,ah
- cbw
- sal ax,1
- mov bx,ax
- mov cx,notes[bx]
- call freq
- ;
- xchg cx,dx
- neg cl
- add cl,8
- sal dx,cl
- ;
- pop ax
- pop bx
- pop cx
- ret
- ;--------------------------------------------------------------
- ; select a tone
- ; input: tone in CX
- ; output: none
- ;
- toneset:push ax
- ;
- mov al,cl
- out 42h,al
- jmp short $+2
- mov al,ch
- out 42h,al
- ;
- pop ax
- ret
- ;--------------------------------------------------------------
- ; turn tone on
- ;
- toneon: push ax
- in al,61H
- or al,3
- out 61h,al
- pop ax
- ret
- ;--------------------------------------------------------------
- ; turn tone off
- ;
- toneoff:push ax
- in al,61h
- and al,0fch
- out 61h,al
- pop ax
- ret
- ;==============================================================
- ; pushbutton routine
- ; output is turned on/off every other push
- ; input is set only by user routine
- ;--------------------------------------------------------------
- public _pusha
- _pusha:
- nextl ; exit
- ;--------------------------------------------------------------
- public upusha
- upusha: mov di,varsav ; point to variable list
- xor byte ptr 8[di],1; flip the output
- pop ax ; keep stack right
- jmp _cancel ; return clean
- ;==============================================================
- ; pushbutton routine
- ; output is a single strobe, lasting from start of loop to priority.
- ; input is set only by user routine
- ;--------------------------------------------------------------
- public _pushb
- _pushb:
- nextt
- ;--------------------------------------------------------------
- public upushb
- upushb: mov di,varsav ; point to variable list
- mov byte ptr 8[di],1; set hi
- pop ax ; keep stack right
- jmp _cancel ; return clean
- ;==============================================================
- ; pushbutton routine
- ; output is incremented/decremented every push, depending on
- ; cursor location on magenta pad.
- ; input is set only by user routine
- ;--------------------------------------------------------------
- public _pushc
- _pushc: nextv ; update screen
- ;--------------------------------------------------------------
- public upushc
- upushc: pop ax ; stack bullshit
- cmp magflg,1 ; inc/dec?
- jnz upushc1 ; no, branch
- ;
- mov di,varsav ; get value table for module
- mov ax,curadr ; up or down button?
- cmp ax,cmdloc ; if same, it's up
- jz upushc2 ; branch if same
- dec byte ptr outn[di] ; dec output value
- jmp _cancel ; exit
- upushc2:inc byte ptr outn[di] ; inc output value
- jmp _cancel ; exit
-
- upushc1:mov cmdflg,10 ; set up special routine
- mov special,offset upushc3 ; data exit
- jmp workx ; exit
-
- upushc3:mov di,varsav ; get value table
- mov al,byte ptr var0[di] ; get new value
- mov byte ptr outn[di],al ; send it out
- jmp _cancel ; exit
- ;==============================================================
- ; Exit routine for modules that use msb of output byte.
- ; It displays output value, then executes the next module on the list.
- ; assumes di has been set to variable table
- ;
- next: mov es,4[di] ; get seg addr
- mov bx,6[di] ; get module screen address
- mov al,8[di] ; get output value
- tohex ; convert to hex word
- mov es:320[bx],ah ; put to the screen
- mov es:322[bx],al ; /
- nextx ; easy exit
- ;--------------------------------------------------------------
- ; Just execute the next module on the list.
- ;
- public _dummy
- _dummy: nextx ; easy exit
-
- ;--------------------------------------------------------------
- ; this code converts in-line macros to jumps at the end of modules
- ;
- public _nextv,_nextx,_nextl,_nextt
- _nextv: @nextv
- _nextx: @nextx
- _nextl: @nextl
- _nextt: @nextt
- ;==============================================================
- ; user input routines for magenta inputs
- ;
- ;--------------------------------------------------------------
- public ugatel
- ugatel: pop ax
- jmp _cancel
- ;==============================================================
- _TEXT ENDS
- END
-
-