[3ae31e9] | 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 | *
|
---|
| 49 | UPD_BIT .equ $0001 * update bit (1 = update)
|
---|
| 50 | INT_BIT .equ $0002 * int. bit (0 = disable)
|
---|
| 51 | RAT_BIT .equ $0004 * ratio bit (0 = ratio)
|
---|
| 52 | *
|
---|
| 53 | VSUBNBIT .equ 3 * new value select bit number
|
---|
| 54 | VAL_BITS .equ $0018 * new value select bit mask
|
---|
| 55 | *
|
---|
| 56 | MSK_RNVB .equ $000C * new value / ratio bits
|
---|
| 57 | MSK_ONVB .equ $0010 * old new value bit
|
---|
| 58 | *
|
---|
| 59 | FKILL .equ $0014 * kill value for function
|
---|
| 60 | FSEND .equ $0015 * send new value to function
|
---|
| 61 | *
|
---|
| 62 | CLREXP .equ $8000 * clear value for time exponent
|
---|
| 63 | CLRMNT .equ $8000 * clear value for time mantissa
|
---|
| 64 | *
|
---|
| 65 | * ------------------------------------------------------------------------------
|
---|
| 66 | * Miscellaneous definitions
|
---|
| 67 | * -------------------------
|
---|
| 68 | *
|
---|
| 69 | PCHMAX .equ 21920 * maximum pitch value
|
---|
| 70 | VALMAX .equ 32000 * maximum value to send to FPU
|
---|
| 71 | VALMIN .equ -32000 * minimum value to send to FPU
|
---|
| 72 | *
|
---|
| 73 | LSPCH .equ 2 * left shift for sources to freq
|
---|
| 74 | *
|
---|
| 75 | VALLEN .equ 10 * length of the 'valent' struct
|
---|
| 76 | VT_VAL .equ 8 * value offset in 'valent'
|
---|
| 77 | *
|
---|
| 78 | .page
|
---|
| 79 | * ------------------------------------------------------------------------------
|
---|
| 80 | * FPU addresses
|
---|
| 81 | * -------------
|
---|
| 82 | *
|
---|
| 83 | FPUBASE .equ $180000 * FPU base address
|
---|
| 84 | *
|
---|
| 85 | FPUWST .equ FPUBASE * FPU waveshape base
|
---|
| 86 | FPUFUNC .equ FPUBASE+$4000 * FPU function base
|
---|
| 87 | FPUINT1 .equ FPUBASE+$4000 * FPU int. input address (R/O)
|
---|
| 88 | FPUINT2 .equ FPUBASE+$6000 * FPU int. reset address (W/O)
|
---|
| 89 | FPUCFG .equ FPUBASE+$5FE0 * FPU config. data address (W/O)
|
---|
| 90 | *
|
---|
| 91 | F_CTL .equ $00 * control word
|
---|
| 92 | F_VAL10 .equ $02 * new value "10"
|
---|
| 93 | F_CV1 .equ $08 * control voltage 1
|
---|
| 94 | F_SF1 .equ $0A * scale factor 1
|
---|
| 95 | F_CV2 .equ $0C * control voltage 2
|
---|
| 96 | F_SF2 .equ $0E * scale factor 2
|
---|
| 97 | F_CV3 .equ $10 * control voltage 3
|
---|
| 98 | F_SF3 .equ $12 * scale factor 3
|
---|
| 99 | F_MNT .equ $14 * time mantissa
|
---|
| 100 | F_EXP .equ $16 * time exponent
|
---|
| 101 | F_VAL01 .equ $1C * new value "01"
|
---|
| 102 | *
|
---|
| 103 | P_FREQ1 .equ $0020 * frequency 1
|
---|
| 104 | P_FREQ2 .equ $0060 * frequency 2
|
---|
| 105 | P_FREQ3 .equ $00A0 * frequency 3
|
---|
| 106 | P_FREQ4 .equ $00E0 * frequency 4
|
---|
| 107 | P_FILTER .equ $0140 * filter
|
---|
| 108 | P_FILTRQ .equ $00C0 * filter q
|
---|
| 109 | *
|
---|
| 110 | P_INDEX1 .equ $0120 * index 1
|
---|
| 111 | P_INDEX2 .equ $0160 * index 2
|
---|
| 112 | P_INDEX3 .equ $0180 * index 3
|
---|
| 113 | P_INDEX4 .equ $01A0 * index 4
|
---|
| 114 | P_INDEX5 .equ $01C0 * index 5
|
---|
| 115 | P_INDEX6 .equ $01E0 * index 6
|
---|
| 116 | *
|
---|
| 117 | P_LEVEL .equ $0040 * level
|
---|
| 118 | *
|
---|
| 119 | P_LOCN .equ $0080 * location
|
---|
| 120 | P_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 | *
|
---|
| 128 | FH_LEN .equ 12 * length of the idfnhdr structure
|
---|
| 129 | *
|
---|
| 130 | FH_PCH .equ 0 * WORD - pitch offset
|
---|
| 131 | FH_MLT .equ 2 * WORD - overall value multiplier
|
---|
| 132 | FH_SRC .equ 4 * BYTE - overall value source
|
---|
| 133 | FH_PIF .equ 5 * BYTE - # of points in the function
|
---|
| 134 | FH_PT1 .equ 6 * BYTE - index of first point
|
---|
| 135 | FH_TMD .equ 7 * BYTE - trigger mode / control bits
|
---|
| 136 | FH_CPT .equ 8 * BYTE - current point
|
---|
| 137 | FH_PRM .equ 9 * BYTE - misc. function parameter
|
---|
| 138 | FH_TRG .equ 10 * WORD - trigger
|
---|
| 139 | *
|
---|
| 140 | I_ACTIVE .equ 1 * 'Active' bit number (in FH_TMD)
|
---|
| 141 | *
|
---|
| 142 | MSK_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 | *
|
---|
| 147 | PT_LEN .equ 12 * length of the instpnt structure
|
---|
| 148 | *
|
---|
| 149 | PT_TIM .equ 0 * WORD - time (packed)
|
---|
| 150 | PT_VAL .equ 2 * WORD - value
|
---|
| 151 | PT_VMLT .equ 4 * WORD - value multiplier
|
---|
| 152 | PT_VSRC .equ 6 * BYTE - value source
|
---|
| 153 | PT_ACT .equ 7 * BYTE - action
|
---|
| 154 | PT_PAR1 .equ 8 * BYTE - parameter 1
|
---|
| 155 | PT_PAR2 .equ 9 * BYTE - parameter 2
|
---|
| 156 | PT_PAR3 .equ 10 * BYTE - parameter 3
|
---|
| 157 | PT_PAD .equ 11 * BYTE - padding for even boundary
|
---|
| 158 | *
|
---|
| 159 | MSK_MNT .equ $FFF0 * mask for mantissa (in PT_TIM)
|
---|
| 160 | MSK_EXP .equ $000F * mask for exponent (in PT_TIM)
|
---|
| 161 | *
|
---|
| 162 | MAX_ACT .equ 7 * maximum action code value
|
---|
| 163 | *
|
---|
| 164 | * ------------------------------------------------------------------------------
|
---|
| 165 | * Source definitions -- must match those in 'smdefs.h'
|
---|
| 166 | *
|
---|
| 167 | SM_RAND .equ 1 * random
|
---|
| 168 | SM_PTCH .equ 5 * pitch
|
---|
| 169 | SM_KPRS .equ 6 * key pressure
|
---|
| 170 | SM_KVEL .equ 7 * key velocity
|
---|
| 171 | SM_FREQ .equ 10 * frequency
|
---|
| 172 | *
|
---|
| 173 | .page
|
---|
| 174 | *
|
---|
| 175 | * Layout of pflist entries 32 bytes each
|
---|
| 176 | * ------------------------
|
---|
| 177 | PF_NEXT .equ 0 * LONG - next entry pointer
|
---|
| 178 | PF_TRIG .equ 4 * WORD - trigger number
|
---|
| 179 | PF_FUNC .equ 6 * WORD - fpuifnc value
|
---|
| 180 | PF_D1 .equ 8 * LONG - d1
|
---|
| 181 | PF_D2 .equ 12 * LONG - d2
|
---|
| 182 | PF_D4 .equ 16 * LONG - d4
|
---|
| 183 | PF_A1 .equ 20 * LONG - a1
|
---|
| 184 | PF_A2 .equ 24 * LONG - a2
|
---|
| 185 | PF_A3 .equ 28 * LONG - a3
|
---|
| 186 | *
|
---|
| 187 | * Parameter offset
|
---|
| 188 | * ----------------
|
---|
| 189 | TRIG .equ 8 * WORD - trigger number
|
---|
| 190 | *
|
---|
| 191 | * Register equates
|
---|
| 192 | * ----------------
|
---|
| 193 | RCUR .equ a4 * current pflist entry pointer
|
---|
| 194 | RPRV .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 | *
|
---|
| 223 | pfpass: movea.l RCUR,RPRV * point at previous entry
|
---|
| 224 | *
|
---|
| 225 | pfscan: 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 | *
|
---|
| 242 | pfnext: 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 | *
|
---|
| 247 | pfexit: 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 | * ------------------------------------------------------------------------------
|
---|
| 257 | stopfn: 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 | * ------------------------------------------------------------------------------
|
---|
| 270 | doact: 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 | * ---- --------------------
|
---|
| 306 | act0: 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 | * ------ ----------------
|
---|
| 318 | outseg: 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 | * ------------------------------------------------------------------------------
|
---|
| 360 | srctyp0: 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 | * ------------------------------------------------------------------------------
|
---|
| 373 | srctyp1: 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 | * ------------------------------------------------------------------------------
|
---|
| 382 | srctyp2: 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 | * ------------------------------------------------------------------------------
|
---|
| 394 | srctyp3: 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 | * ------------------------------------------------------------------------------
|
---|
| 407 | srctyp4: 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 | * ------------------------------------------------------------------------------
|
---|
| 425 | applym: 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 | *
|
---|
| 436 | srcmlt1: cmpi.l #VALMIN,d5 * check for underflow
|
---|
| 437 | bge srcmlt2 * jump if no underflow
|
---|
| 438 | *
|
---|
| 439 | move.l #VALMIN,d5 * limit at VALMIN
|
---|
| 440 | *
|
---|
| 441 | srcmlt2: move.w d5,d3 * setup value for output to FPU
|
---|
| 442 | *
|
---|
| 443 | .page
|
---|
| 444 | * ------------------------------------------------------------------------------
|
---|
| 445 | * adjust the value according to the function type
|
---|
| 446 | * ------------------------------------------------------------------------------
|
---|
| 447 | nosrc: 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 | *
|
---|
| 464 | outsegc: 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 | *
|
---|
| 469 | outsegl: tst.w d3 * check sign of value
|
---|
| 470 | bpl outsegm * jump if positive
|
---|
| 471 | *
|
---|
| 472 | clr.w d3 * limit negative values at 0
|
---|
| 473 | *
|
---|
| 474 | outsegm: 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 | * ------------------------------------------------------------------------------
|
---|
| 483 | outsegf: 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 | *
|
---|
| 500 | outsega: 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 | * ------------------------------------------------------------------------------
|
---|
| 510 | outsegp: cmpi.w #P_FREQ1,d0 * see if it's freq1
|
---|
| 511 | beq outseg0 * go process freq1
|
---|
| 512 | *
|
---|
| 513 | outsegq: 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 | *
|
---|
| 522 | outseg0: 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 | * ------------------------------------------------------------------------------
|
---|
| 537 | outseg3: 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 | *
|
---|
| 546 | outseg1: move.w d3,F_VAL10(a3,d1.W) * send value to FPU
|
---|
| 547 | *
|
---|
| 548 | outseg2: 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 | * ---- ----------------------------
|
---|
| 558 | act2: 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 | * ---- -----------------------------
|
---|
| 581 | act3: 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 | * ---- ----------------------------------------------
|
---|
| 599 | act4: 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 | *
|
---|
| 616 | act4b: 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 | *
|
---|
| 621 | act4a: 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 | * ---- ----------------------------
|
---|
| 629 | act5: 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 | * ---- ------------------------------
|
---|
| 654 | act6: 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 | * ------------------------------------------------------------------------------
|
---|
| 675 | act7: bra act0 * AC_HERE: treat act7 as AC_NULL
|
---|
| 676 | *
|
---|
| 677 | .page
|
---|
| 678 | *
|
---|
| 679 | * act1 -- AC_SUST -- pause if key is down (sustain)
|
---|
| 680 | * ---- -----------------------------------------
|
---|
| 681 | act1: 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 | *
|
---|
| 699 | act1a: 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 | * ----- --------------------------
|
---|
| 733 | actab: 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
|
---|