source: buchla-68k/ram/procpfl.s@ 84c0125

Last change on this file since 84c0125 was 4cfe69a, checked in by Thomas Lopatic <thomas@…>, 7 years ago

Use .ds and .dc pseudo-ops. Generate debug symbols.

  • Property mode set to 100644
File size: 24.7 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 = 0x0001 | update bit (1 = update)
50INT_BIT = 0x0002 | int. bit (0 = disable)
51RAT_BIT = 0x0004 | ratio bit (0 = ratio)
52
53VSUBNBIT = 3 | new value select bit number
54VAL_BITS = 0x0018 | new value select bit mask
55
56MSK_RNVB = 0x000C | new value / ratio bits
57MSK_ONVB = 0x0010 | old new value bit
58
59FKILL = 0x0014 | kill value for function
60FSEND = 0x0015 | send new value to function
61
62CLREXP = 0x8000 | clear value for time exponent
63CLRMNT = 0x8000 | clear value for time mantissa
64
65| ------------------------------------------------------------------------------
66| Miscellaneous definitions
67| -------------------------
68
69PCHMAX = 21920 | maximum pitch value
70VALMAX = 32000 | maximum value to send to FPU
71VALMIN = -32000 | minimum value to send to FPU
72
73LSPCH = 2 | left shift for sources to freq
74
75VALLEN = 10 | length of the 'valent' struct
76VT_VAL = 8 | value offset in 'valent'
77
78 .page
79| ------------------------------------------------------------------------------
80| FPU addresses
81| -------------
82
83FPUBASE = 0x180000 | FPU base address
84
85FPUWST = FPUBASE | FPU waveshape base
86FPUFUNC = FPUBASE+0x4000 | FPU function base
87FPUINT1 = FPUBASE+0x4000 | FPU int. input address (R/O)
88FPUINT2 = FPUBASE+0x6000 | FPU int. reset address (W/O)
89FPUCFG = FPUBASE+0x5FE0 | FPU config. data address (W/O)
90
91F_CTL = 0x00 | control word
92F_VAL10 = 0x02 | new value "10"
93F_CV1 = 0x08 | control voltage 1
94F_SF1 = 0x0A | scale factor 1
95F_CV2 = 0x0C | control voltage 2
96F_SF2 = 0x0E | scale factor 2
97F_CV3 = 0x10 | control voltage 3
98F_SF3 = 0x12 | scale factor 3
99F_MNT = 0x14 | time mantissa
100F_EXP = 0x16 | time exponent
101F_VAL01 = 0x1C | new value "01"
102
103P_FREQ1 = 0x0020 | frequency 1
104P_FREQ2 = 0x0060 | frequency 2
105P_FREQ3 = 0x00A0 | frequency 3
106P_FREQ4 = 0x00E0 | frequency 4
107P_FILTER = 0x0140 | filter
108P_FILTRQ = 0x00C0 | filter q
109
110P_INDEX1 = 0x0120 | index 1
111P_INDEX2 = 0x0160 | index 2
112P_INDEX3 = 0x0180 | index 3
113P_INDEX4 = 0x01A0 | index 4
114P_INDEX5 = 0x01C0 | index 5
115P_INDEX6 = 0x01E0 | index 6
116
117P_LEVEL = 0x0040 | level
118
119P_LOCN = 0x0080 | location
120P_DYNAM = 0x0100 | dynamics
121
122 .page
123| ------------------------------------------------------------------------------
124| Structure definitions
125| ------------------------------------------------------------------------------
126| The following MUST match the idfnhdr structure definition in instdsp.h:
127
128FH_LEN = 12 | length of the idfnhdr structure
129
130FH_PCH = 0 | WORD - pitch offset
131FH_MLT = 2 | WORD - overall value multiplier
132FH_SRC = 4 | BYTE - overall value source
133FH_PIF = 5 | BYTE - # of points in the function
134FH_PT1 = 6 | BYTE - index of first point
135FH_TMD = 7 | BYTE - trigger mode / control bits
136FH_CPT = 8 | BYTE - current point
137FH_PRM = 9 | BYTE - misc. function parameter
138FH_TRG = 10 | WORD - trigger
139
140I_ACTIVE = 1 | 'Active' bit number (in FH_TMD)
141
142MSK_CTL = 0x001C | 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 = 12 | length of the instpnt structure
148
149PT_TIM = 0 | WORD - time (packed)
150PT_VAL = 2 | WORD - value
151PT_VMLT = 4 | WORD - value multiplier
152PT_VSRC = 6 | BYTE - value source
153PT_ACT = 7 | BYTE - action
154PT_PAR1 = 8 | BYTE - parameter 1
155PT_PAR2 = 9 | BYTE - parameter 2
156PT_PAR3 = 10 | BYTE - parameter 3
157PT_PAD = 11 | BYTE - padding for even boundary
158
159MSK_MNT = 0xFFF0 | mask for mantissa (in PT_TIM)
160MSK_EXP = 0x000F | mask for exponent (in PT_TIM)
161
162MAX_ACT = 7 | maximum action code value
163
164| ------------------------------------------------------------------------------
165| Source definitions -- must match those in 'smdefs.h'
166
167SM_RAND = 1 | random
168SM_PTCH = 5 | pitch
169SM_KPRS = 6 | key pressure
170SM_KVEL = 7 | key velocity
171SM_FREQ = 10 | frequency
172
173 .page
174
175| Layout of pflist entries 32 bytes each
176| ------------------------
177PF_NEXT = 0 | LONG - next entry pointer
178PF_TRIG = 4 | WORD - trigger number
179PF_FUNC = 6 | WORD - fpuifnc value
180PF_D1 = 8 | LONG - d1
181PF_D2 = 12 | LONG - d2
182PF_D4 = 16 | LONG - d4
183PF_A1 = 20 | LONG - a1
184PF_A2 = 24 | LONG - a2
185PF_A3 = 28 | LONG - a3
186
187| Parameter offset
188| ----------------
189TRIG = 8 | WORD - trigger number
190
191| Register equates
192| ----------------
193RCUR = a4 | current pflist entry pointer
194RPRV = 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 #0x2200,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 #0x01FE,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 #0x001E,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 #0x01E0,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 #0x001E,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 #0x001E,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 #0x001E,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 #0x001E,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.