source: buchla-68k/orig/RAM/PROCPFL.S@ 66b48e7

Last change on this file since 66b48e7 was 3ae31e9, checked in by Thomas Lopatic <thomas@…>, 7 years ago

Imported original source code.

  • Property mode set to 100755
File size: 25.8 KB
Line 
1* ------------------------------------------------------------------------------
2* procpfl.s -- process pendant functions (sustain release processing)
3* Version 8 -- 1988-08-31 -- D.N. Lynx Crowe
4* ------------------------------------------------------------------------------
5 .text
6*
7 .xdef _procpfl
8*
9 .xdef _curpf_f * current function (v/p)
10 .xdef _curpf_l * current pflist entry
11 .xdef _curpf_t * current trigger
12*
13 .xref _irand
14 .xref _xgetran
15*
16 .xref _expbit
17 .xref _funcndx
18 .xref _pflist
19 .xref _pfqhdr
20 .xref _prstab
21 .xref _ptoftab
22 .xref _timemlt
23 .xref _trgtab
24 .xref _valents
25 .xref _vce2grp
26 .xref _vce2trg
27 .xref _veltab
28*
29 .page
30* ------------------------------------------------------------------------------
31* Register usage
32* --------------
33* d0 scratch
34* d1 FPU function index
35* d2 point index from FH_CPT (idfcpt)
36* d3 scratch
37* d4 jump point number from PT_PAR1 (ippar1)
38* d5 scratch
39*
40* a0 scratch
41* a1 function header base
42* a2 point table base
43* a3 FPU base
44*
45* ------------------------------------------------------------------------------
46* FPU definitions
47* ---------------
48*
49UPD_BIT .equ $0001 * update bit (1 = update)
50INT_BIT .equ $0002 * int. bit (0 = disable)
51RAT_BIT .equ $0004 * ratio bit (0 = ratio)
52*
53VSUBNBIT .equ 3 * new value select bit number
54VAL_BITS .equ $0018 * new value select bit mask
55*
56MSK_RNVB .equ $000C * new value / ratio bits
57MSK_ONVB .equ $0010 * old new value bit
58*
59FKILL .equ $0014 * kill value for function
60FSEND .equ $0015 * send new value to function
61*
62CLREXP .equ $8000 * clear value for time exponent
63CLRMNT .equ $8000 * clear value for time mantissa
64*
65* ------------------------------------------------------------------------------
66* Miscellaneous definitions
67* -------------------------
68*
69PCHMAX .equ 21920 * maximum pitch value
70VALMAX .equ 32000 * maximum value to send to FPU
71VALMIN .equ -32000 * minimum value to send to FPU
72*
73LSPCH .equ 2 * left shift for sources to freq
74*
75VALLEN .equ 10 * length of the 'valent' struct
76VT_VAL .equ 8 * value offset in 'valent'
77*
78 .page
79* ------------------------------------------------------------------------------
80* FPU addresses
81* -------------
82*
83FPUBASE .equ $180000 * FPU base address
84*
85FPUWST .equ FPUBASE * FPU waveshape base
86FPUFUNC .equ FPUBASE+$4000 * FPU function base
87FPUINT1 .equ FPUBASE+$4000 * FPU int. input address (R/O)
88FPUINT2 .equ FPUBASE+$6000 * FPU int. reset address (W/O)
89FPUCFG .equ FPUBASE+$5FE0 * FPU config. data address (W/O)
90*
91F_CTL .equ $00 * control word
92F_VAL10 .equ $02 * new value "10"
93F_CV1 .equ $08 * control voltage 1
94F_SF1 .equ $0A * scale factor 1
95F_CV2 .equ $0C * control voltage 2
96F_SF2 .equ $0E * scale factor 2
97F_CV3 .equ $10 * control voltage 3
98F_SF3 .equ $12 * scale factor 3
99F_MNT .equ $14 * time mantissa
100F_EXP .equ $16 * time exponent
101F_VAL01 .equ $1C * new value "01"
102*
103P_FREQ1 .equ $0020 * frequency 1
104P_FREQ2 .equ $0060 * frequency 2
105P_FREQ3 .equ $00A0 * frequency 3
106P_FREQ4 .equ $00E0 * frequency 4
107P_FILTER .equ $0140 * filter
108P_FILTRQ .equ $00C0 * filter q
109*
110P_INDEX1 .equ $0120 * index 1
111P_INDEX2 .equ $0160 * index 2
112P_INDEX3 .equ $0180 * index 3
113P_INDEX4 .equ $01A0 * index 4
114P_INDEX5 .equ $01C0 * index 5
115P_INDEX6 .equ $01E0 * index 6
116*
117P_LEVEL .equ $0040 * level
118*
119P_LOCN .equ $0080 * location
120P_DYNAM .equ $0100 * dynamics
121*
122 .page
123* ------------------------------------------------------------------------------
124* Structure definitions
125* ------------------------------------------------------------------------------
126* The following MUST match the idfnhdr structure definition in instdsp.h:
127*
128FH_LEN .equ 12 * length of the idfnhdr structure
129*
130FH_PCH .equ 0 * WORD - pitch offset
131FH_MLT .equ 2 * WORD - overall value multiplier
132FH_SRC .equ 4 * BYTE - overall value source
133FH_PIF .equ 5 * BYTE - # of points in the function
134FH_PT1 .equ 6 * BYTE - index of first point
135FH_TMD .equ 7 * BYTE - trigger mode / control bits
136FH_CPT .equ 8 * BYTE - current point
137FH_PRM .equ 9 * BYTE - misc. function parameter
138FH_TRG .equ 10 * WORD - trigger
139*
140I_ACTIVE .equ 1 * 'Active' bit number (in FH_TMD)
141*
142MSK_CTL .equ $001C * mask for FPU hardware bits (in FH_TMD)
143*
144* ------------------------------------------------------------------------------
145* The following MUST match the instpnt structure definition in instdsp.h:
146*
147PT_LEN .equ 12 * length of the instpnt structure
148*
149PT_TIM .equ 0 * WORD - time (packed)
150PT_VAL .equ 2 * WORD - value
151PT_VMLT .equ 4 * WORD - value multiplier
152PT_VSRC .equ 6 * BYTE - value source
153PT_ACT .equ 7 * BYTE - action
154PT_PAR1 .equ 8 * BYTE - parameter 1
155PT_PAR2 .equ 9 * BYTE - parameter 2
156PT_PAR3 .equ 10 * BYTE - parameter 3
157PT_PAD .equ 11 * BYTE - padding for even boundary
158*
159MSK_MNT .equ $FFF0 * mask for mantissa (in PT_TIM)
160MSK_EXP .equ $000F * mask for exponent (in PT_TIM)
161*
162MAX_ACT .equ 7 * maximum action code value
163*
164* ------------------------------------------------------------------------------
165* Source definitions -- must match those in 'smdefs.h'
166*
167SM_RAND .equ 1 * random
168SM_PTCH .equ 5 * pitch
169SM_KPRS .equ 6 * key pressure
170SM_KVEL .equ 7 * key velocity
171SM_FREQ .equ 10 * frequency
172*
173 .page
174*
175* Layout of pflist entries 32 bytes each
176* ------------------------
177PF_NEXT .equ 0 * LONG - next entry pointer
178PF_TRIG .equ 4 * WORD - trigger number
179PF_FUNC .equ 6 * WORD - fpuifnc value
180PF_D1 .equ 8 * LONG - d1
181PF_D2 .equ 12 * LONG - d2
182PF_D4 .equ 16 * LONG - d4
183PF_A1 .equ 20 * LONG - a1
184PF_A2 .equ 24 * LONG - a2
185PF_A3 .equ 28 * LONG - a3
186*
187* Parameter offset
188* ----------------
189TRIG .equ 8 * WORD - trigger number
190*
191* Register equates
192* ----------------
193RCUR .equ a4 * current pflist entry pointer
194RPRV .equ a5 * previous pflist entry pointer
195*
196 .page
197* ------------------------------------------------------------------------------
198* _procpfl() -- process pendant functions
199*
200* void
201* procpfl(trig);
202* unsigned trig;
203*
204* Processes pendant (sustained) functions by restarting them
205* when the trigger (trig) that's sustaining them is released.
206* Invoked by key release processing in msm() and localkb().
207*
208* ------------------------------------------------------------------------------
209*
210_procpfl: nop * FOR DEBUGGING PATCH
211*
212 link a6,#0 * allocate stack frame
213 movem.l d3-d7/a3-a5,-(a7) * preserve registers we use
214*
215 move.w sr,d7 * save interrupt state
216 move.w #$2200,sr * turn off FPU interrupts
217*
218 move.w TRIG(a6),d6 * get trigger we're processing
219 move.w d6,_curpf_t * ...
220 movea.l #_pflist,RPRV * point at 'previous' pflist entry
221 bra pfscan * go scan the chain
222*
223pfpass: movea.l RCUR,RPRV * point at previous entry
224*
225pfscan: move.l (RPRV),d5 * get next pflist entry pointer
226 beq pfexit * done if no more
227*
228 movea.l d5,RCUR * point at current entry
229 move.l d5,_curpf_l * ...
230*
231 cmp.w PF_TRIG(RCUR),d6 * see if this entry is wanted
232 bne pfpass * jump if not
233*
234 movem.l PF_D1(RCUR),d1-d2/d4/a1-a3 * restore processing state
235 move.w PF_FUNC(RCUR),_curpf_f * ...
236*
237 btst #I_ACTIVE,FH_TMD(a1) * see if function is active
238 bne doact * continue function if so
239*
240 bra stopfn * stop function if not
241*
242pfnext: move.l (RCUR),(RPRV) * remove entry from pflist
243 move.l _pfqhdr,(RCUR) * chain entry to free list
244 move.l RCUR,_pfqhdr * ...
245 bra pfscan * go look at next entry
246*
247pfexit: move.w d7,sr * restore interrupt level
248 movem.l (a7)+,d3-d7/a3-a5 * restore the registers we used
249 unlk a6 * deallocate stack frame
250 rts * return to caller
251*
252 .page
253*
254* ------------------------------------------------------------------------------
255* stop a function
256* ------------------------------------------------------------------------------
257stopfn: move.b FH_TMD(a1),d0 * get function control bits
258 andi.w #MSK_RNVB,d0 * mask for ratio / new new-value bit
259 move.w d0,d3 * isolate new new-value bit
260 add.w d3,d3 * ... from function header
261 andi.w #MSK_ONVB,d3 * ... shift to old new-value bit
262 or.w d3,d0 * ... and put new bit in old bit
263 move.w d0,F_CTL(a3,d1.W) * stop the function
264 bclr #I_ACTIVE,FH_TMD(a1) * reset the active bit
265 bra pfnext * go restore registers and exit
266*
267* ------------------------------------------------------------------------------
268* setup for and dispatch to the proper action handler
269* ------------------------------------------------------------------------------
270doact: clr.w d2 * get current point index in d2
271 move.b FH_CPT(a1),d2 * ...
272 lsl.w #2,d2 * multiply it by the length of a point
273 move.w d2,d0 * ... (fast multiply by PT_LEN = 12
274 add.w d2,d2 * ... via shift and add)
275 add.w d0,d2 * ...
276 clr.w d4 * get jump point # into d4
277 move.b PT_PAR1(a2,d2.W),d4 * ...
278 clr.w d3 * get action code in d3
279 move.b PT_ACT(a2,d2.W),d3 * ...
280 cmpi.b #MAX_ACT,d3 * check against the limit
281 bgt stopfn * stop things if it's a bad action code
282*
283 lsl.w #2,d3 * develop index to action dispatch table
284 lea actab,a0 * get the address of the action handler
285 movea.l 0(a0,d3.W),a0 * ...
286*
287* ------------------------------------------------------------------------------
288* At this point we're ready to do the action associated with the point,
289* and the registers are set up, and will remain, as follows:
290*
291* d1 FPU function index a1 function header base
292* d2 point table index a2 point table base
293* a3 FPU function base
294* d4 jump point number
295*
296* d0, d3, d5, and a0 are used as scratch throughout the code.
297*
298* ------------------------------------------------------------------------------
299*
300 jmp (a0) * dispatch to action handler
301*
302 .page
303* ------------------------------------------------------------------------------
304* act0 -- AC_NULL -- no action
305* ---- --------------------
306act0: move.b FH_PT1(a1),d0 * get first point number
307 add.b FH_PIF(a1),d0 * add number of points in function
308 subq.b #1,d0 * make it last point number
309 cmp.b FH_CPT(a1),d0 * see if we're at the last point
310 beq stopfn * stop function if so
311*
312 addq.b #1,FH_CPT(a1) * update function header for next point
313 addi.w #PT_LEN,d2 * advance the point index
314*
315* ------------------------------------------------------------------------------
316* outseg -- output a segment
317* ------ ----------------
318outseg: move.w PT_TIM(a2,d2.w),d3 * get packed time
319 move.w d3,d0 * extract mantissa
320 andi.w #MSK_MNT,d0 * ...
321 mulu _timemlt,d0 * multiply by panel time pot value
322 lsr.l #8,d0 * ... and scale it
323 lsr.l #7,d0 * ...
324 move.w d0,F_MNT(a3,d1.W) * send mantissa to FPU
325 andi.w #MSK_EXP,d3 * extract exponent code
326 add.w d3,d3 * look up decoded exponent
327 lea _expbit,a0 * ... in expbit
328 move.w 0(a0,d3.W),F_EXP(a3,d1.W) * send exponent to FPU
329 move.w PT_VAL(a2,d2.W),d3 * get the function value
330*
331 .page
332* ------------------------------------------------------------------------------
333* get the point source, if any
334* ------------------------------------------------------------------------------
335 tst.w PT_VMLT(a2,d2.W) * see if we have a point mlt.
336 beq nosrc * don't do anything for zero
337*
338 clr.w d0 * get the source number
339 move.b PT_VSRC(a2,d2.W),d0 * ...
340 beq nosrc * don't do anything for zero
341*
342* ------------------------------------------------------------------------------
343* SM_RAND -- random
344* ------------------------------------------------------------------------------
345 cmpi.w #SM_RAND,d0 * is this the random source ?
346 bne srctyp0 * jump if not
347*
348 movem.l d1-d2/a0-a2,-(a7) * preserve registers around call
349 move.w PT_VMLT(a2,d2.W),-(a7) * pass multiplier to xgetran()
350 jsr _xgetran * call for a random number
351 tst.w (a7)+ * clean up stack
352 movem.l (a7)+,d1-d2/a0-a2 * restore registers
353 move.w d0,d5 * put random value in the value register
354 bra applym * go apply the multiplier
355*
356 .page
357* ------------------------------------------------------------------------------
358* SM_FREQ -- frequency
359* ------------------------------------------------------------------------------
360srctyp0: cmpi.w #SM_FREQ,d0 * is this the frequency source ?
361 bne srctyp1 * jump if not
362*
363 move.w (a1),d0 * get the pitch
364 lsr.w #6,d0 * shift to a word index
365 andi.w #$01FE,d0 * mask out extraneous bits
366 lea _ptoftab,a0 * get entry from ptoftab[]
367 move.w 0(a0,d0.W),d5 * ...
368 bra applym * go apply the multiplier
369*
370* ------------------------------------------------------------------------------
371* SM_PTCH -- pitch
372* ------------------------------------------------------------------------------
373srctyp1: cmpi.w #SM_PTCH,d0 * is this the pitch source ?
374 bne srctyp2 * jump if not
375*
376 move.w (a1),d5 * get the pitch as the value
377 bra applym * go apply the multiplier
378*
379* ------------------------------------------------------------------------------
380* SM_KVEL -- velocity
381* ------------------------------------------------------------------------------
382srctyp2: cmpi.w #SM_KVEL,d0 * is this the key velocity source ?
383 bne srctyp3 * jump if not
384*
385 move.w FH_TRG(a1),d0 * get the trigger number
386 add.w d0,d0 * ... as a word index
387 lea _veltab,a0 * ... into veltab[]
388 move.w 0(a0,d0.W),d5 * get the velocity from veltab[trg]
389 bra applym * go apply the multiplier
390*
391* ------------------------------------------------------------------------------
392* SM_KPRS -- pressure
393* ------------------------------------------------------------------------------
394srctyp3: cmpi.w #SM_KPRS,d0 * is this the key pressure source ?
395 bne srctyp4 * jump if not (must be an analog input)
396*
397 move.w FH_TRG(a1),d0 * get the trigger number
398 add.w d0,d0 * ... as a word index
399 lea _prstab,a0 * ... into prstab[]
400 move.w 0(a0,d0.W),d5 * get the pressure from prstab[trg]
401 bra applym * go apply the multiplier
402*
403 .page
404* ------------------------------------------------------------------------------
405* all other sources come out of the valents[] array
406* ------------------------------------------------------------------------------
407srctyp4: lea _vce2grp,a0 * point at vce2grp[]
408 move.w _curpf_f,d5 * get voice number in d5
409 lsr.w #3,d5 * ...
410 andi.w #$001E,d5 * ... as a word index
411 move.w 0(a0,d5.W),d5 * get the group number
412 subq.w #1,d5 * ...
413 lsl.w #4,d5 * shift it left a nybble
414 or.w d5,d0 * OR it into the source number
415 add.w d0,d0 * make source number a valents[] index
416 move.w d0,d5 * ... (fast multiply by VALLEN = 10
417 lsl.w #2,d0 * ... via shift and add)
418 add.w d5,d0 * ...
419 lea _valents,a0 * get base of valents[]
420 move.w VT_VAL(a0,d0.W),d5 * get value
421*
422* ------------------------------------------------------------------------------
423* apply the multiplier to the source, and add it to the function value
424* ------------------------------------------------------------------------------
425applym: muls PT_VMLT(a2,d2.W),d5 * apply the multiplier
426 asr.l #7,d5 * scale the result
427 asr.l #8,d5 * ...
428 ext.l d3 * add the function value
429 add.l d3,d5 * ...
430 cmpi.l #VALMAX,d5 * check for overflow
431 ble srcmlt1 * jump if no overflow
432*
433 move.l #VALMAX,d5 * limit at VALMAX
434 bra srcmlt2 * ...
435*
436srcmlt1: cmpi.l #VALMIN,d5 * check for underflow
437 bge srcmlt2 * jump if no underflow
438*
439 move.l #VALMIN,d5 * limit at VALMIN
440*
441srcmlt2: move.w d5,d3 * setup value for output to FPU
442*
443 .page
444* ------------------------------------------------------------------------------
445* adjust the value according to the function type
446* ------------------------------------------------------------------------------
447nosrc: move.w d1,d0 * get function type
448 andi.w #$01E0,d0 * ...
449*
450* ------------------------------------------------------------------------------
451* level or location
452* ------------------------------------------------------------------------------
453 cmpi.w #P_LEVEL,d0 * see if it's the level
454 beq outsegl * jump if so
455*
456 cmpi.w #P_LOCN,d0 * see if it's the location
457 bne outsegf * jump if not
458*
459 tst.w d3 * check sign of value
460 bpl outsegc * jump if positive
461*
462 clr.w d3 * force negative values to 0
463*
464outsegc: asr.w #5,d3 * shift value to LS bits
465 sub.w #500,d3 * subtract 5.00 from value
466 asl.w #6,d3 * readjust to MS bits
467 bra outseg3 * go output the value
468*
469outsegl: tst.w d3 * check sign of value
470 bpl outsegm * jump if positive
471*
472 clr.w d3 * limit negative values at 0
473*
474outsegm: asr.w #5,d3 * shift value to LS bits
475 sub.w #500,d3 * subtract 5.00 from value
476 asl.w #6,d3 * readjust to MS bits
477 bra outseg3 * go output the value
478*
479 .page
480* ------------------------------------------------------------------------------
481* filter
482* ------------------------------------------------------------------------------
483outsegf: cmpi.w #P_FILTER,d0 * see if it's the filter
484 bne outsegp * jump if not
485*
486 ext.l d3 * make function value a long
487 asr.l #1,d3 * multiply function value by .75
488 move.l d3,d0 * ... (fast multiply by .75
489 asr.l #1,d0 * ... via shift and add)
490 add.l d0,d3 * ...
491 move.w (a1),d0 * add pitch
492 ext.l d0 * ...
493 add.l d0,d3 * ...
494 cmpi.l #VALMAX,d3 * see if it's within limits
495 ble outsega * ...
496*
497 move.w #VALMAX,d3 * limit at VALMAX
498 bra outseg3 * ...
499*
500outsega: cmpi.l #VALMIN,d3 * ...
501 bge outseg3 * ...
502*
503 move.w #VALMIN,d3 * limit at VALMIN
504 bra outseg3 * ...
505*
506 .page
507* ------------------------------------------------------------------------------
508* freq 1..4
509* ------------------------------------------------------------------------------
510outsegp: cmpi.w #P_FREQ1,d0 * see if it's freq1
511 beq outseg0 * go process freq1
512*
513outsegq: cmpi.w #P_FREQ2,d0 * see if it's freq2
514 beq outseg0 * process it if so
515*
516 cmpi.w #P_FREQ3,d0 * see if it's freq3
517 beq outseg0 * process it if so
518*
519 cmpi.w #P_FREQ4,d0 * see if it's freq4
520 bne outseg3 * jump if not
521*
522outseg0: ext.l d3 * scale the point value to cents offset
523 asr.l #5,d3 * ...
524 sub.l #500,d3 * ... value - 500
525 asl.l #LSPCH,d3 * mult. by 2 and scale for 1/2 cent lsb
526 move.w (a1),d0 * add pitch from function header
527 ext.l d0 * ...
528 add.l d0,d3 * ...
529 cmp.l #PCHMAX,d3 * see if result is valid
530 ble outseg3 * jump if within pitch limits
531*
532 move.l #PCHMAX,d3 * limit at maximum pitch
533*
534* ------------------------------------------------------------------------------
535* send the value to the FPU
536* ------------------------------------------------------------------------------
537outseg3: move.b FH_TMD(a1),d0 * get hardware bits from function header
538 eor.w #VAL_BITS,d0 * toggle new value select bits
539 move.b d0,FH_TMD(a1) * store updated word
540 btst.l #VSUBNBIT,d0 * check which value address to use
541 beq outseg1
542*
543 move.w d3,F_VAL01(a3,d1.W) * send value to FPU
544 bra outseg2
545*
546outseg1: move.w d3,F_VAL10(a3,d1.W) * send value to FPU
547*
548outseg2: andi.w #MSK_CTL,d0 * mask off software bits
549 ori.w #UPD_BIT+INT_BIT,d0 * set the update & !lastseg bits
550 move.w d0,F_CTL(a3,d1.W) * send control word to FPU
551 bra pfnext * done -- exit
552*
553 .page
554*
555* ------------------------------------------------------------------------------
556* act2 -- AC_ENBL -- stop if key is up
557* ---- ----------------------------
558act2: move.w _curpf_f,d0 * get voice as a word index
559 lsr.w #3,d0 * ...
560 andi.w #$001E,d0 * ...
561 lea _vce2trg,a0 * check to see if voice is free
562 move.w 0(a0,d0.W),d0 * ...
563 cmpi.w #-1,d0 * ...
564 beq stopfn * if so, stop the function
565*
566 btst #15,d0 * see if voice is held
567 bne act0 * continue if so
568*
569 btst #14,d0 * ...
570 bne act0 * ...
571*
572 lea _trgtab,a0 * check trigger table entry
573 tst.b 0(a0,d0.W) * ...
574 bne act0 * if trigger is active, continue
575*
576 bra stopfn * if not, stop the function
577*
578* ------------------------------------------------------------------------------
579* act3 -- AC_JUMP -- unconditional jump
580* ---- -----------------------------
581act3: cmp.b FH_PIF(a1),d4 * check jump point against limit
582 bcc stopfn * stop function if jump point invalid
583*
584 clr.w d2 * get index of first point
585 move.b FH_PT1(a1),d2 * ...
586 add.b d4,d2 * add jump point
587 move.b d2,FH_CPT(a1) * make it the current point
588 lsl.w #2,d2 * develop new point index in d2
589 move.w d2,d0 * ... (fast multiply by PT_LEN = 12
590 add.w d2,d2 * ... via shift and add)
591 add.w d0,d2 * ...
592 bra outseg * output the segment
593*
594 .page
595*
596* ------------------------------------------------------------------------------
597* act4 -- AC_LOOP -- jump to point PT_PAR1 PT_PAR2 times
598* ---- ----------------------------------------------
599act4: tst.b PT_PAR3(a2,d2.W) * check counter
600 bne act4a * jump if it's running
601*
602 move.b PT_PAR2(a2,d2.W),d0 * get parameter
603 subi.w #90,d0 * put parameter in random range
604 bmi act4b * treat as normal if < 90
605*
606 movem.l d1-d2/a0-a2,-(a7) * get ranged random number
607 move.w d0,-(a7) * ...
608 jsr _irand * ...
609 tst.w (a7)+ * ...
610 movem.l (a7)+,d1-d2/a0-a2 * ...
611 move.b d0,PT_PAR3(a2,d2.w) * set counter
612 beq act0 * next segment if cntr set to 0
613*
614 bra act3 * else jump to the point
615*
616act4b: move.b PT_PAR2(a2,d2.W),PT_PAR3(a2,d2.W) * set counter
617 beq act0 * next segment if cntr set to 0
618*
619 bra act3 * else jump to the point
620*
621act4a: subq.b #1,PT_PAR3(a2,d2.W) * decrement counter
622 beq act0 * next segment if cntr ran out
623*
624 bra act3 * jump if it's still non-zero
625*
626* ------------------------------------------------------------------------------
627* act5 -- AC_KYUP -- jump if key is up
628* ---- ----------------------------
629act5: move.w _curpf_f,d0 * get voice as a word index
630 lsr.w #3,d0 * ...
631 andi.w #$001E,d0 * ...
632 lea _vce2trg,a0 * check to see if voice is free
633 move.w 0(a0,d0.W),d0 * ...
634 cmpi.w #-1,d0 * ...
635 beq act3 * if so (inactive), do the jump
636*
637 btst #15,d0 * see if voice is held
638 bne act0 * continue if so
639*
640 btst #14,d0 * ...
641 bne act0 * ...
642*
643 lea _trgtab,a0 * check trigger table entry
644 tst.b 0(a0,d0.W) * see if the trigger is active
645 beq act3 * if not, do the jump
646*
647 bra act0 * if so, do next segment
648*
649 .page
650*
651* ------------------------------------------------------------------------------
652* act6 -- AC_KYDN -- jump if key is down
653* ---- ------------------------------
654act6: move.w _curpf_f,d0 * get voice as a word index
655 lsr.w #3,d0 * ...
656 andi.w #$001E,d0 * ...
657 lea _vce2trg,a0 * check to see if voice is free
658 move.w 0(a0,d0.W),d0 * ...
659 cmpi.w #-1,d0 * ...
660 beq act0 * if so (inactive), continue
661*
662 btst #15,d0 * see if voice is held
663 bne act3 * do jump if so
664*
665 btst #14,d0 * ...
666 bne act3 * ...
667*
668 lea _trgtab,a0 * check trigger table entry
669 tst.b 0(a0,d0.W) * see if the trigger is active
670 bne act3 * if so, do the jump
671*
672 bra act0 * if not, do next segment
673*
674* ------------------------------------------------------------------------------
675act7: bra act0 * AC_HERE: treat act7 as AC_NULL
676*
677 .page
678*
679* act1 -- AC_SUST -- pause if key is down (sustain)
680* ---- -----------------------------------------
681act1: move.w _curpf_f,d0 * get voice as a word index
682 lsr.w #3,d0 * ...
683 andi.w #$001E,d0 * ...
684 lea _vce2trg,a0 * point at voice to trigger table
685 move.w 0(a0,d0.W),d0 * get trigger table entry
686 cmpi.w #-1,d0 * see if voice is free
687 beq act0 * treat as no-op if so
688*
689 btst #15,d0 * see if voice is held by a pedal
690 bne act1a * sustain if so
691*
692 btst #14,d0 * see if voice is sustained by a pedal
693 bne act1a * sustain if so
694*
695 lea _trgtab,a0 * point at trigger table
696 tst.b 0(a0,d0.W) * check trigger status
697 beq act0 * continue if not active
698*
699act1a: move.l _pfqhdr,d3 * see if any pflist entries remain
700 beq act0 * no-op if not (shouldn't happen ...)
701*
702 move.b FH_PT1(a1),d0 * get first point number
703 add.b FH_PIF(a1),d0 * add base to first point
704 subq.b #1,d0 * make d0 last point number
705 cmp.b FH_CPT(a1),d0 * check current point number
706 beq stopfn * done if this is the last point
707*
708 addq.b #1,FH_CPT(a1) * update current point number
709 addi.w #PT_LEN,d2 * update point index
710 movea.l d3,a0 * acquire a new pflist entry
711 move.l (a0),_pfqhdr * ...
712 move.l _pflist,(a0) * ...
713 move.l a0,_pflist * ...
714 move.w FH_TRG(a1),PF_TRIG(a0) * set trigger number in entry
715 move.w _curpf_f,PF_FUNC(a0) * set v/p word in entry
716 movem.l d1-d2/d4/a1-a3,PF_D1(a0) * set registers in entry
717 move.b FH_TMD(a1),d0 * stop the function
718 andi.w #MSK_RNVB,d0 * ...
719 move.w d0,d3 * ...
720 add.w d3,d3 * ...
721 andi.w #MSK_ONVB,d3 * ...
722 or.w d3,d0 * ...
723 move.w d0,F_CTL(a3,d1.W) * ...
724 bra pfnext * go do next list entry
725*
726 .page
727* ------------------------------------------------------------------------------
728 .data
729* ------------------------------------------------------------------------------
730*
731* actab -- action code dispatch table
732* ----- --------------------------
733actab: dc.l act0 * 0 - AC_NULL: no action
734 dc.l act1 * 1 - AC_SUST: sustain
735 dc.l act2 * 2 - AC_ENBL: enable
736 dc.l act3 * 3 - AC_JUMP: unconditional jump
737 dc.l act4 * 4 - AC_LOOP: jump n times (loop)
738 dc.l act5 * 5 - AC_KYUP: jump if key up (enable jump)
739 dc.l act6 * 6 - AC_KYDN: jump if key down (sustain jump)
740 dc.l act7 * 7 - AC_HERE: here on key up
741*
742* ------------------------------------------------------------------------------
743 .bss
744* ------------------------------------------------------------------------------
745*
746* ----------------- local variables --------------------------------------------
747*
748_curpf_f: ds.w 1 * interrupting voice & parameter from FPU
749*
750* ----------------- debug variables --------------------------------------------
751*
752_curpf_t: ds.w 1 * current trigger
753*
754_curpf_l: ds.l 1 * current pflist entry
755*
756* ------------------------------------------------------------------------------
757*
758 .end
Note: See TracBrowser for help on using the repository browser.