| ------------------------------------------------------------------------------ | procpfl.s -- process pendant functions (sustain release processing) | Version 8 -- 1988-08-31 -- D.N. Lynx Crowe | ------------------------------------------------------------------------------ .text .xdef procpfl .xdef _curpf_f | current function (v/p) .xdef _curpf_l | current pflist entry .xdef _curpf_t | current trigger .xref irand .xref xgetran .xref expbit .xref funcndx .xref pflist .xref pfqhdr .xref prstab .xref ptoftab .xref timemlt .xref trgtab .xref valents .xref vce2grp .xref vce2trg .xref veltab .page | ------------------------------------------------------------------------------ | Register usage | -------------- | d0 scratch | d1 FPU function index | d2 point index from FH_CPT (idfcpt) | d3 scratch | d4 jump point number from PT_PAR1 (ippar1) | d5 scratch | a0 scratch | a1 function header base | a2 point table base | a3 FPU base | ------------------------------------------------------------------------------ | FPU definitions | --------------- UPD_BIT = 0x0001 | update bit (1 = update) INT_BIT = 0x0002 | int. bit (0 = disable) RAT_BIT = 0x0004 | ratio bit (0 = ratio) VSUBNBIT = 3 | new value select bit number VAL_BITS = 0x0018 | new value select bit mask MSK_RNVB = 0x000C | new value / ratio bits MSK_ONVB = 0x0010 | old new value bit FKILL = 0x0014 | kill value for function FSEND = 0x0015 | send new value to function CLREXP = 0x8000 | clear value for time exponent CLRMNT = 0x8000 | clear value for time mantissa | ------------------------------------------------------------------------------ | Miscellaneous definitions | ------------------------- PCHMAX = 21920 | maximum pitch value VALMAX = 32000 | maximum value to send to FPU VALMIN = -32000 | minimum value to send to FPU LSPCH = 2 | left shift for sources to freq VALLEN = 10 | length of the 'valent' struct VT_VAL = 8 | value offset in 'valent' .page | ------------------------------------------------------------------------------ | FPU addresses | ------------- FPUBASE = 0x180000 | FPU base address FPUWST = FPUBASE | FPU waveshape base FPUFUNC = FPUBASE+0x4000 | FPU function base FPUINT1 = FPUBASE+0x4000 | FPU int. input address (R/O) FPUINT2 = FPUBASE+0x6000 | FPU int. reset address (W/O) FPUCFG = FPUBASE+0x5FE0 | FPU config. data address (W/O) F_CTL = 0x00 | control word F_VAL10 = 0x02 | new value "10" F_CV1 = 0x08 | control voltage 1 F_SF1 = 0x0A | scale factor 1 F_CV2 = 0x0C | control voltage 2 F_SF2 = 0x0E | scale factor 2 F_CV3 = 0x10 | control voltage 3 F_SF3 = 0x12 | scale factor 3 F_MNT = 0x14 | time mantissa F_EXP = 0x16 | time exponent F_VAL01 = 0x1C | new value "01" P_FREQ1 = 0x0020 | frequency 1 P_FREQ2 = 0x0060 | frequency 2 P_FREQ3 = 0x00A0 | frequency 3 P_FREQ4 = 0x00E0 | frequency 4 P_FILTER = 0x0140 | filter P_FILTRQ = 0x00C0 | filter q P_INDEX1 = 0x0120 | index 1 P_INDEX2 = 0x0160 | index 2 P_INDEX3 = 0x0180 | index 3 P_INDEX4 = 0x01A0 | index 4 P_INDEX5 = 0x01C0 | index 5 P_INDEX6 = 0x01E0 | index 6 P_LEVEL = 0x0040 | level P_LOCN = 0x0080 | location P_DYNAM = 0x0100 | dynamics .page | ------------------------------------------------------------------------------ | Structure definitions | ------------------------------------------------------------------------------ | The following MUST match the idfnhdr structure definition in instdsp.h: FH_LEN = 12 | length of the idfnhdr structure FH_PCH = 0 | WORD - pitch offset FH_MLT = 2 | WORD - overall value multiplier FH_SRC = 4 | BYTE - overall value source FH_PIF = 5 | BYTE - # of points in the function FH_PT1 = 6 | BYTE - index of first point FH_TMD = 7 | BYTE - trigger mode / control bits FH_CPT = 8 | BYTE - current point FH_PRM = 9 | BYTE - misc. function parameter FH_TRG = 10 | WORD - trigger I_ACTIVE = 1 | 'Active' bit number (in FH_TMD) MSK_CTL = 0x001C | mask for FPU hardware bits (in FH_TMD) | ------------------------------------------------------------------------------ | The following MUST match the instpnt structure definition in instdsp.h: PT_LEN = 12 | length of the instpnt structure PT_TIM = 0 | WORD - time (packed) PT_VAL = 2 | WORD - value PT_VMLT = 4 | WORD - value multiplier PT_VSRC = 6 | BYTE - value source PT_ACT = 7 | BYTE - action PT_PAR1 = 8 | BYTE - parameter 1 PT_PAR2 = 9 | BYTE - parameter 2 PT_PAR3 = 10 | BYTE - parameter 3 PT_PAD = 11 | BYTE - padding for even boundary MSK_MNT = 0xFFF0 | mask for mantissa (in PT_TIM) MSK_EXP = 0x000F | mask for exponent (in PT_TIM) MAX_ACT = 7 | maximum action code value | ------------------------------------------------------------------------------ | Source definitions -- must match those in 'smdefs.h' SM_RAND = 1 | random SM_PTCH = 5 | pitch SM_KPRS = 6 | key pressure SM_KVEL = 7 | key velocity SM_FREQ = 10 | frequency .page | Layout of pflist entries 32 bytes each | ------------------------ PF_NEXT = 0 | LONG - next entry pointer PF_TRIG = 4 | WORD - trigger number PF_FUNC = 6 | WORD - fpuifnc value PF_D1 = 8 | LONG - d1 PF_D2 = 12 | LONG - d2 PF_D4 = 16 | LONG - d4 PF_A1 = 20 | LONG - a1 PF_A2 = 24 | LONG - a2 PF_A3 = 28 | LONG - a3 | Parameter offset | ---------------- TRIG = 8 | WORD - trigger number | Register equates | ---------------- RCUR = a4 | current pflist entry pointer RPRV = a5 | previous pflist entry pointer .page | ------------------------------------------------------------------------------ | procpfl() -- process pendant functions | void | procpfl(trig); | unsigned trig; | Processes pendant (sustained) functions by restarting them | when the trigger (trig) that's sustaining them is released. | Invoked by key release processing in msm() and localkb(). | ------------------------------------------------------------------------------ procpfl: nop | FOR DEBUGGING PATCH link a6,#0 | allocate stack frame movem.l d3-d7/a3-a5,-(a7) | preserve registers we use move.w sr,d7 | save interrupt state move.w #0x2200,sr | turn off FPU interrupts move.w TRIG(a6),d6 | get trigger we're processing move.w d6,_curpf_t | ... movea.l #pflist,RPRV | point at 'previous' pflist entry bra pfscan | go scan the chain pfpass: movea.l RCUR,RPRV | point at previous entry pfscan: move.l (RPRV),d5 | get next pflist entry pointer beq pfexit | done if no more movea.l d5,RCUR | point at current entry move.l d5,_curpf_l | ... cmp.w PF_TRIG(RCUR),d6 | see if this entry is wanted bne pfpass | jump if not movem.l PF_D1(RCUR),d1-d2/d4/a1-a3 | restore processing state move.w PF_FUNC(RCUR),_curpf_f | ... btst #I_ACTIVE,FH_TMD(a1) | see if function is active bne doact | continue function if so bra stopfn | stop function if not pfnext: move.l (RCUR),(RPRV) | remove entry from pflist move.l pfqhdr,(RCUR) | chain entry to free list move.l RCUR,pfqhdr | ... bra pfscan | go look at next entry pfexit: move.w d7,sr | restore interrupt level movem.l (a7)+,d3-d7/a3-a5 | restore the registers we used unlk a6 | deallocate stack frame rts | return to caller .page | ------------------------------------------------------------------------------ | stop a function | ------------------------------------------------------------------------------ stopfn: move.b FH_TMD(a1),d0 | get function control bits andi.w #MSK_RNVB,d0 | mask for ratio / new new-value bit move.w d0,d3 | isolate new new-value bit add.w d3,d3 | ... from function header andi.w #MSK_ONVB,d3 | ... shift to old new-value bit or.w d3,d0 | ... and put new bit in old bit move.w d0,F_CTL(a3,d1.W) | stop the function bclr #I_ACTIVE,FH_TMD(a1) | reset the active bit bra pfnext | go restore registers and exit | ------------------------------------------------------------------------------ | setup for and dispatch to the proper action handler | ------------------------------------------------------------------------------ doact: clr.w d2 | get current point index in d2 move.b FH_CPT(a1),d2 | ... lsl.w #2,d2 | multiply it by the length of a point move.w d2,d0 | ... (fast multiply by PT_LEN = 12 add.w d2,d2 | ... via shift and add) add.w d0,d2 | ... clr.w d4 | get jump point # into d4 move.b PT_PAR1(a2,d2.W),d4 | ... clr.w d3 | get action code in d3 move.b PT_ACT(a2,d2.W),d3 | ... cmpi.b #MAX_ACT,d3 | check against the limit bgt stopfn | stop things if it's a bad action code lsl.w #2,d3 | develop index to action dispatch table lea actab,a0 | get the address of the action handler movea.l 0(a0,d3.W),a0 | ... | ------------------------------------------------------------------------------ | At this point we're ready to do the action associated with the point, | and the registers are set up, and will remain, as follows: | d1 FPU function index a1 function header base | d2 point table index a2 point table base | a3 FPU function base | d4 jump point number | d0, d3, d5, and a0 are used as scratch throughout the code. | ------------------------------------------------------------------------------ jmp (a0) | dispatch to action handler .page | ------------------------------------------------------------------------------ | act0 -- AC_NULL -- no action | ---- -------------------- act0: move.b FH_PT1(a1),d0 | get first point number add.b FH_PIF(a1),d0 | add number of points in function subq.b #1,d0 | make it last point number cmp.b FH_CPT(a1),d0 | see if we're at the last point beq stopfn | stop function if so addq.b #1,FH_CPT(a1) | update function header for next point addi.w #PT_LEN,d2 | advance the point index | ------------------------------------------------------------------------------ | outseg -- output a segment | ------ ---------------- outseg: move.w PT_TIM(a2,d2.w),d3 | get packed time move.w d3,d0 | extract mantissa andi.w #MSK_MNT,d0 | ... mulu timemlt,d0 | multiply by panel time pot value lsr.l #8,d0 | ... and scale it lsr.l #7,d0 | ... move.w d0,F_MNT(a3,d1.W) | send mantissa to FPU andi.w #MSK_EXP,d3 | extract exponent code add.w d3,d3 | look up decoded exponent lea expbit,a0 | ... in expbit move.w 0(a0,d3.W),F_EXP(a3,d1.W) | send exponent to FPU move.w PT_VAL(a2,d2.W),d3 | get the function value .page | ------------------------------------------------------------------------------ | get the point source, if any | ------------------------------------------------------------------------------ tst.w PT_VMLT(a2,d2.W) | see if we have a point mlt. beq nosrc | don't do anything for zero clr.w d0 | get the source number move.b PT_VSRC(a2,d2.W),d0 | ... beq nosrc | don't do anything for zero | ------------------------------------------------------------------------------ | SM_RAND -- random | ------------------------------------------------------------------------------ cmpi.w #SM_RAND,d0 | is this the random source ? bne srctyp0 | jump if not movem.l d1-d2/a0-a2,-(a7) | preserve registers around call move.w PT_VMLT(a2,d2.W),-(a7) | pass multiplier to xgetran() jsr xgetran | call for a random number tst.w (a7)+ | clean up stack movem.l (a7)+,d1-d2/a0-a2 | restore registers move.w d0,d5 | put random value in the value register bra applym | go apply the multiplier .page | ------------------------------------------------------------------------------ | SM_FREQ -- frequency | ------------------------------------------------------------------------------ srctyp0: cmpi.w #SM_FREQ,d0 | is this the frequency source ? bne srctyp1 | jump if not move.w (a1),d0 | get the pitch lsr.w #6,d0 | shift to a word index andi.w #0x01FE,d0 | mask out extraneous bits lea ptoftab,a0 | get entry from ptoftab[] move.w 0(a0,d0.W),d5 | ... bra applym | go apply the multiplier | ------------------------------------------------------------------------------ | SM_PTCH -- pitch | ------------------------------------------------------------------------------ srctyp1: cmpi.w #SM_PTCH,d0 | is this the pitch source ? bne srctyp2 | jump if not move.w (a1),d5 | get the pitch as the value bra applym | go apply the multiplier | ------------------------------------------------------------------------------ | SM_KVEL -- velocity | ------------------------------------------------------------------------------ srctyp2: cmpi.w #SM_KVEL,d0 | is this the key velocity source ? bne srctyp3 | jump if not move.w FH_TRG(a1),d0 | get the trigger number add.w d0,d0 | ... as a word index lea veltab,a0 | ... into veltab[] move.w 0(a0,d0.W),d5 | get the velocity from veltab[trg] bra applym | go apply the multiplier | ------------------------------------------------------------------------------ | SM_KPRS -- pressure | ------------------------------------------------------------------------------ srctyp3: cmpi.w #SM_KPRS,d0 | is this the key pressure source ? bne srctyp4 | jump if not (must be an analog input) move.w FH_TRG(a1),d0 | get the trigger number add.w d0,d0 | ... as a word index lea prstab,a0 | ... into prstab[] move.w 0(a0,d0.W),d5 | get the pressure from prstab[trg] bra applym | go apply the multiplier .page | ------------------------------------------------------------------------------ | all other sources come out of the valents[] array | ------------------------------------------------------------------------------ srctyp4: lea vce2grp,a0 | point at vce2grp[] move.w _curpf_f,d5 | get voice number in d5 lsr.w #3,d5 | ... andi.w #0x001E,d5 | ... as a word index move.w 0(a0,d5.W),d5 | get the group number subq.w #1,d5 | ... lsl.w #4,d5 | shift it left a nybble or.w d5,d0 | OR it into the source number add.w d0,d0 | make source number a valents[] index move.w d0,d5 | ... (fast multiply by VALLEN = 10 lsl.w #2,d0 | ... via shift and add) add.w d5,d0 | ... lea valents,a0 | get base of valents[] move.w VT_VAL(a0,d0.W),d5 | get value | ------------------------------------------------------------------------------ | apply the multiplier to the source, and add it to the function value | ------------------------------------------------------------------------------ applym: muls PT_VMLT(a2,d2.W),d5 | apply the multiplier asr.l #7,d5 | scale the result asr.l #8,d5 | ... ext.l d3 | add the function value add.l d3,d5 | ... cmpi.l #VALMAX,d5 | check for overflow ble srcmlt1 | jump if no overflow move.l #VALMAX,d5 | limit at VALMAX bra srcmlt2 | ... srcmlt1: cmpi.l #VALMIN,d5 | check for underflow bge srcmlt2 | jump if no underflow move.l #VALMIN,d5 | limit at VALMIN srcmlt2: move.w d5,d3 | setup value for output to FPU .page | ------------------------------------------------------------------------------ | adjust the value according to the function type | ------------------------------------------------------------------------------ nosrc: move.w d1,d0 | get function type andi.w #0x01E0,d0 | ... | ------------------------------------------------------------------------------ | level or location | ------------------------------------------------------------------------------ cmpi.w #P_LEVEL,d0 | see if it's the level beq outsegl | jump if so cmpi.w #P_LOCN,d0 | see if it's the location bne outsegf | jump if not tst.w d3 | check sign of value bpl outsegc | jump if positive clr.w d3 | force negative values to 0 outsegc: asr.w #5,d3 | shift value to LS bits sub.w #500,d3 | subtract 5.00 from value asl.w #6,d3 | readjust to MS bits bra outseg3 | go output the value outsegl: tst.w d3 | check sign of value bpl outsegm | jump if positive clr.w d3 | limit negative values at 0 outsegm: asr.w #5,d3 | shift value to LS bits sub.w #500,d3 | subtract 5.00 from value asl.w #6,d3 | readjust to MS bits bra outseg3 | go output the value .page | ------------------------------------------------------------------------------ | filter | ------------------------------------------------------------------------------ outsegf: cmpi.w #P_FILTER,d0 | see if it's the filter bne outsegp | jump if not ext.l d3 | make function value a long asr.l #1,d3 | multiply function value by .75 move.l d3,d0 | ... (fast multiply by .75 asr.l #1,d0 | ... via shift and add) add.l d0,d3 | ... move.w (a1),d0 | add pitch ext.l d0 | ... add.l d0,d3 | ... cmpi.l #VALMAX,d3 | see if it's within limits ble outsega | ... move.w #VALMAX,d3 | limit at VALMAX bra outseg3 | ... outsega: cmpi.l #VALMIN,d3 | ... bge outseg3 | ... move.w #VALMIN,d3 | limit at VALMIN bra outseg3 | ... .page | ------------------------------------------------------------------------------ | freq 1..4 | ------------------------------------------------------------------------------ outsegp: cmpi.w #P_FREQ1,d0 | see if it's freq1 beq outseg0 | go process freq1 outsegq: cmpi.w #P_FREQ2,d0 | see if it's freq2 beq outseg0 | process it if so cmpi.w #P_FREQ3,d0 | see if it's freq3 beq outseg0 | process it if so cmpi.w #P_FREQ4,d0 | see if it's freq4 bne outseg3 | jump if not outseg0: ext.l d3 | scale the point value to cents offset asr.l #5,d3 | ... sub.l #500,d3 | ... value - 500 asl.l #LSPCH,d3 | mult. by 2 and scale for 1/2 cent lsb move.w (a1),d0 | add pitch from function header ext.l d0 | ... add.l d0,d3 | ... cmp.l #PCHMAX,d3 | see if result is valid ble outseg3 | jump if within pitch limits move.l #PCHMAX,d3 | limit at maximum pitch | ------------------------------------------------------------------------------ | send the value to the FPU | ------------------------------------------------------------------------------ outseg3: move.b FH_TMD(a1),d0 | get hardware bits from function header eor.w #VAL_BITS,d0 | toggle new value select bits move.b d0,FH_TMD(a1) | store updated word btst.l #VSUBNBIT,d0 | check which value address to use beq outseg1 move.w d3,F_VAL01(a3,d1.W) | send value to FPU bra outseg2 outseg1: move.w d3,F_VAL10(a3,d1.W) | send value to FPU outseg2: andi.w #MSK_CTL,d0 | mask off software bits ori.w #UPD_BIT+INT_BIT,d0 | set the update & !lastseg bits move.w d0,F_CTL(a3,d1.W) | send control word to FPU bra pfnext | done -- exit .page | ------------------------------------------------------------------------------ | act2 -- AC_ENBL -- stop if key is up | ---- ---------------------------- act2: move.w _curpf_f,d0 | get voice as a word index lsr.w #3,d0 | ... andi.w #0x001E,d0 | ... lea vce2trg,a0 | check to see if voice is free move.w 0(a0,d0.W),d0 | ... cmpi.w #-1,d0 | ... beq stopfn | if so, stop the function btst #15,d0 | see if voice is held bne act0 | continue if so btst #14,d0 | ... bne act0 | ... lea trgtab,a0 | check trigger table entry tst.b 0(a0,d0.W) | ... bne act0 | if trigger is active, continue bra stopfn | if not, stop the function | ------------------------------------------------------------------------------ | act3 -- AC_JUMP -- unconditional jump | ---- ----------------------------- act3: cmp.b FH_PIF(a1),d4 | check jump point against limit bcc stopfn | stop function if jump point invalid clr.w d2 | get index of first point move.b FH_PT1(a1),d2 | ... add.b d4,d2 | add jump point move.b d2,FH_CPT(a1) | make it the current point lsl.w #2,d2 | develop new point index in d2 move.w d2,d0 | ... (fast multiply by PT_LEN = 12 add.w d2,d2 | ... via shift and add) add.w d0,d2 | ... bra outseg | output the segment .page | ------------------------------------------------------------------------------ | act4 -- AC_LOOP -- jump to point PT_PAR1 PT_PAR2 times | ---- ---------------------------------------------- act4: tst.b PT_PAR3(a2,d2.W) | check counter bne act4a | jump if it's running move.b PT_PAR2(a2,d2.W),d0 | get parameter subi.w #90,d0 | put parameter in random range bmi act4b | treat as normal if < 90 movem.l d1-d2/a0-a2,-(a7) | get ranged random number move.w d0,-(a7) | ... jsr irand | ... tst.w (a7)+ | ... movem.l (a7)+,d1-d2/a0-a2 | ... move.b d0,PT_PAR3(a2,d2.w) | set counter beq act0 | next segment if cntr set to 0 bra act3 | else jump to the point act4b: move.b PT_PAR2(a2,d2.W),PT_PAR3(a2,d2.W) | set counter beq act0 | next segment if cntr set to 0 bra act3 | else jump to the point act4a: subq.b #1,PT_PAR3(a2,d2.W) | decrement counter beq act0 | next segment if cntr ran out bra act3 | jump if it's still non-zero | ------------------------------------------------------------------------------ | act5 -- AC_KYUP -- jump if key is up | ---- ---------------------------- act5: move.w _curpf_f,d0 | get voice as a word index lsr.w #3,d0 | ... andi.w #0x001E,d0 | ... lea vce2trg,a0 | check to see if voice is free move.w 0(a0,d0.W),d0 | ... cmpi.w #-1,d0 | ... beq act3 | if so (inactive), do the jump btst #15,d0 | see if voice is held bne act0 | continue if so btst #14,d0 | ... bne act0 | ... lea trgtab,a0 | check trigger table entry tst.b 0(a0,d0.W) | see if the trigger is active beq act3 | if not, do the jump bra act0 | if so, do next segment .page | ------------------------------------------------------------------------------ | act6 -- AC_KYDN -- jump if key is down | ---- ------------------------------ act6: move.w _curpf_f,d0 | get voice as a word index lsr.w #3,d0 | ... andi.w #0x001E,d0 | ... lea vce2trg,a0 | check to see if voice is free move.w 0(a0,d0.W),d0 | ... cmpi.w #-1,d0 | ... beq act0 | if so (inactive), continue btst #15,d0 | see if voice is held bne act3 | do jump if so btst #14,d0 | ... bne act3 | ... lea trgtab,a0 | check trigger table entry tst.b 0(a0,d0.W) | see if the trigger is active bne act3 | if so, do the jump bra act0 | if not, do next segment | ------------------------------------------------------------------------------ act7: bra act0 | AC_HERE: treat act7 as AC_NULL .page | act1 -- AC_SUST -- pause if key is down (sustain) | ---- ----------------------------------------- act1: move.w _curpf_f,d0 | get voice as a word index lsr.w #3,d0 | ... andi.w #0x001E,d0 | ... lea vce2trg,a0 | point at voice to trigger table move.w 0(a0,d0.W),d0 | get trigger table entry cmpi.w #-1,d0 | see if voice is free beq act0 | treat as no-op if so btst #15,d0 | see if voice is held by a pedal bne act1a | sustain if so btst #14,d0 | see if voice is sustained by a pedal bne act1a | sustain if so lea trgtab,a0 | point at trigger table tst.b 0(a0,d0.W) | check trigger status beq act0 | continue if not active act1a: move.l pfqhdr,d3 | see if any pflist entries remain beq act0 | no-op if not (shouldn't happen ...) move.b FH_PT1(a1),d0 | get first point number add.b FH_PIF(a1),d0 | add base to first point subq.b #1,d0 | make d0 last point number cmp.b FH_CPT(a1),d0 | check current point number beq stopfn | done if this is the last point addq.b #1,FH_CPT(a1) | update current point number addi.w #PT_LEN,d2 | update point index movea.l d3,a0 | acquire a new pflist entry move.l (a0),pfqhdr | ... move.l pflist,(a0) | ... move.l a0,pflist | ... move.w FH_TRG(a1),PF_TRIG(a0) | set trigger number in entry move.w _curpf_f,PF_FUNC(a0) | set v/p word in entry movem.l d1-d2/d4/a1-a3,PF_D1(a0) | set registers in entry move.b FH_TMD(a1),d0 | stop the function andi.w #MSK_RNVB,d0 | ... move.w d0,d3 | ... add.w d3,d3 | ... andi.w #MSK_ONVB,d3 | ... or.w d3,d0 | ... move.w d0,F_CTL(a3,d1.W) | ... bra pfnext | go do next list entry .page | ------------------------------------------------------------------------------ .data | ------------------------------------------------------------------------------ | actab -- action code dispatch table | ----- -------------------------- actab: .dc.l act0 | 0 - AC_NULL: no action .dc.l act1 | 1 - AC_SUST: sustain .dc.l act2 | 2 - AC_ENBL: enable .dc.l act3 | 3 - AC_JUMP: unconditional jump .dc.l act4 | 4 - AC_LOOP: jump n times (loop) .dc.l act5 | 5 - AC_KYUP: jump if key up (enable jump) .dc.l act6 | 6 - AC_KYDN: jump if key down (sustain jump) .dc.l act7 | 7 - AC_HERE: here on key up | ------------------------------------------------------------------------------ .bss | ------------------------------------------------------------------------------ | ----------------- local variables -------------------------------------------- _curpf_f: .ds.w 1 | interrupting voice & parameter from FPU | ----------------- debug variables -------------------------------------------- _curpf_t: .ds.w 1 | current trigger _curpf_l: .ds.l 1 | current pflist entry | ------------------------------------------------------------------------------ .end