[4f508e6] | 1 | | ------------------------------------------------------------------------------
|
---|
| 2 | | fpuint.s -- process FPU interrupts / clear FPU
|
---|
| 3 | | Version 63 -- 1988-08-31 -- D.N. Lynx Crowe
|
---|
| 4 | | ------------------------------------------------------------------------------
|
---|
[f40a309] | 5 | .text
|
---|
[4f508e6] | 6 |
|
---|
[8325447] | 7 | .xdef fpuint | process an FPU interrupt
|
---|
| 8 | .xdef fpuclr | reset the FPU
|
---|
| 9 | .xdef clrvce | quiet a voice
|
---|
| 10 |
|
---|
| 11 | .xdef fputrap | a very good debug trap point
|
---|
| 12 |
|
---|
| 13 | .xdef fp_resv | 'spare' function reset value table
|
---|
| 14 | .xdef fpuifnc | FPU interrupt code (voice / function)
|
---|
| 15 |
|
---|
| 16 | .xref irand | ranged random number function
|
---|
| 17 | .xref scope | diagnostic scope function
|
---|
| 18 | .xref xgetran | random number function
|
---|
| 19 |
|
---|
| 20 | .xref expbit
|
---|
| 21 | .xref funcndx
|
---|
| 22 | .xref initcfg
|
---|
| 23 | .xref ndisp
|
---|
| 24 | .xref pflist
|
---|
| 25 | .xref pfqhdr
|
---|
| 26 | .xref prstab
|
---|
| 27 | .xref ptoftab
|
---|
| 28 | .xref scopef
|
---|
| 29 | .xref timemlt
|
---|
| 30 | .xref trgtab
|
---|
| 31 | .xref valents
|
---|
| 32 | .xref vce2grp
|
---|
| 33 | .xref vce2trg
|
---|
| 34 | .xref veltab
|
---|
[4f508e6] | 35 |
|
---|
[f40a309] | 36 | .page
|
---|
[4f508e6] | 37 | | ------------------------------------------------------------------------------
|
---|
| 38 | | Register usage
|
---|
| 39 | | --------------
|
---|
| 40 | | d0 scratch
|
---|
| 41 | | d1 FPU function index
|
---|
| 42 | | d2 point index from FH_CPT (idfcpt)
|
---|
| 43 | | d3 scratch
|
---|
| 44 | | d4 jump point number from PT_PAR1 (ippar1)
|
---|
| 45 | | d5 scratch
|
---|
| 46 |
|
---|
| 47 | | a0 scratch
|
---|
| 48 | | a1 function header base
|
---|
| 49 | | a2 point table base
|
---|
| 50 | | a3 FPU base
|
---|
| 51 |
|
---|
| 52 | | ------------------------------------------------------------------------------
|
---|
| 53 | | FPU definitions
|
---|
| 54 | | ---------------
|
---|
| 55 |
|
---|
| 56 | UPD_BIT = 0x0001 | update bit (1 = update)
|
---|
| 57 | INT_BIT = 0x0002 | int. bit (0 = disable)
|
---|
| 58 | RAT_BIT = 0x0004 | ratio bit (0 = ratio)
|
---|
| 59 |
|
---|
| 60 | VSUBNBIT = 3 | new value select bit number
|
---|
| 61 | VAL_BITS = 0x0018 | new value select bit mask
|
---|
| 62 |
|
---|
| 63 | MSK_RNVB = 0x000C | new value / ratio bits
|
---|
| 64 | MSK_ONVB = 0x0010 | old new value bit
|
---|
| 65 |
|
---|
| 66 | FKILL = 0x0014 | kill value for function
|
---|
| 67 | FSEND = 0x0015 | send new value to function
|
---|
| 68 |
|
---|
| 69 | CLREXP = 0x8000 | clear value for time exponent
|
---|
| 70 | CLRMNT = 0x8000 | clear value for time mantissa
|
---|
| 71 |
|
---|
| 72 | | ------------------------------------------------------------------------------
|
---|
| 73 | | Miscellaneous definitions
|
---|
| 74 | | -------------------------
|
---|
| 75 |
|
---|
| 76 | PCHMAX = 21920 | maximum pitch value
|
---|
| 77 | VALMAX = 32000 | maximum value to send to FPU
|
---|
| 78 | VALMIN = -32000 | minimum value to send to FPU
|
---|
| 79 |
|
---|
| 80 | LSPCH = 2 | left shift for sources to freq
|
---|
| 81 |
|
---|
| 82 | VALLEN = 10 | length of the 'valent' struct
|
---|
| 83 | VT_VAL = 8 | value offset in 'valent'
|
---|
| 84 |
|
---|
[f40a309] | 85 | .page
|
---|
[4f508e6] | 86 | | ------------------------------------------------------------------------------
|
---|
| 87 | | FPU addresses
|
---|
| 88 | | -------------
|
---|
| 89 |
|
---|
| 90 | FPUBASE = 0x180000 | FPU base address
|
---|
| 91 |
|
---|
| 92 | FPUWST = FPUBASE | FPU waveshape base
|
---|
| 93 | FPUFUNC = FPUBASE+0x4000 | FPU function base
|
---|
| 94 | FPUINT1 = FPUBASE+0x4000 | FPU int. input address (R/O)
|
---|
| 95 | FPUINT2 = FPUBASE+0x6000 | FPU int. reset address (W/O)
|
---|
| 96 | FPUCFG = FPUBASE+0x5FE0 | FPU config. data address (W/O)
|
---|
| 97 |
|
---|
| 98 | F_CTL = 0x00 | control word
|
---|
| 99 | F_VAL10 = 0x02 | new value "10"
|
---|
| 100 | F_CV1 = 0x08 | control voltage 1
|
---|
| 101 | F_SF1 = 0x0A | scale factor 1
|
---|
| 102 | F_CV2 = 0x0C | control voltage 2
|
---|
| 103 | F_SF2 = 0x0E | scale factor 2
|
---|
| 104 | F_CV3 = 0x10 | control voltage 3
|
---|
| 105 | F_SF3 = 0x12 | scale factor 3
|
---|
| 106 | F_MNT = 0x14 | time mantissa
|
---|
| 107 | F_EXP = 0x16 | time exponent
|
---|
| 108 | F_VAL01 = 0x1C | new value "01"
|
---|
| 109 |
|
---|
| 110 | P_FREQ1 = 0x0020 | frequency 1
|
---|
| 111 | P_FREQ2 = 0x0060 | frequency 2
|
---|
| 112 | P_FREQ3 = 0x00A0 | frequency 3
|
---|
| 113 | P_FREQ4 = 0x00E0 | frequency 4
|
---|
| 114 | P_FILTER = 0x0140 | filter
|
---|
| 115 | P_FILTRQ = 0x00C0 | filter q
|
---|
| 116 |
|
---|
| 117 | P_INDEX1 = 0x0120 | index 1
|
---|
| 118 | P_INDEX2 = 0x0160 | index 2
|
---|
| 119 | P_INDEX3 = 0x0180 | index 3
|
---|
| 120 | P_INDEX4 = 0x01A0 | index 4
|
---|
| 121 | P_INDEX5 = 0x01C0 | index 5
|
---|
| 122 | P_INDEX6 = 0x01E0 | index 6
|
---|
| 123 |
|
---|
| 124 | P_LEVEL = 0x0040 | level
|
---|
| 125 |
|
---|
| 126 | P_LOCN = 0x0080 | location
|
---|
| 127 | P_DYNAM = 0x0100 | dynamics
|
---|
| 128 |
|
---|
[f40a309] | 129 | .page
|
---|
[4f508e6] | 130 | | ------------------------------------------------------------------------------
|
---|
| 131 | | Structure definitions
|
---|
| 132 | | ------------------------------------------------------------------------------
|
---|
| 133 | | The following MUST match the idfnhdr structure definition in instdsp.h:
|
---|
| 134 |
|
---|
| 135 | FH_LEN = 12 | length of the idfnhdr structure
|
---|
| 136 |
|
---|
| 137 | FH_PCH = 0 | WORD - pitch offset (freq1 only)
|
---|
| 138 | FH_MLT = 2 | WORD - overall value multiplier
|
---|
| 139 | FH_SRC = 4 | BYTE - overall value source
|
---|
| 140 | FH_PIF = 5 | BYTE - # of points in the function
|
---|
| 141 | FH_PT1 = 6 | BYTE - index of first point
|
---|
| 142 | FH_TMD = 7 | BYTE - trigger mode / control bits
|
---|
| 143 | FH_CPT = 8 | BYTE - current point
|
---|
| 144 | FH_PRM = 9 | BYTE - misc. function parameter
|
---|
| 145 | FH_TRG = 10 | WORD - trigger
|
---|
| 146 |
|
---|
| 147 | I_ACTIVE = 1 | 'Active' bit number (in FH_TMD)
|
---|
| 148 |
|
---|
| 149 | MSK_CTL = 0x001C | mask for FPU hardware bits (in FH_TMD)
|
---|
| 150 |
|
---|
| 151 | | ------------------------------------------------------------------------------
|
---|
| 152 | | The following MUST match the instpnt structure definition in instdsp.h:
|
---|
| 153 |
|
---|
| 154 | PT_LEN = 12 | length of the instpnt structure
|
---|
| 155 |
|
---|
| 156 | PT_TIM = 0 | WORD - time (packed)
|
---|
| 157 | PT_VAL = 2 | WORD - value
|
---|
| 158 | PT_VMLT = 4 | WORD - value multiplier
|
---|
| 159 | PT_VSRC = 6 | BYTE - value source
|
---|
| 160 | PT_ACT = 7 | BYTE - action
|
---|
| 161 | PT_PAR1 = 8 | BYTE - parameter 1
|
---|
| 162 | PT_PAR2 = 9 | BYTE - parameter 2
|
---|
| 163 | PT_PAR3 = 10 | BYTE - parameter 3
|
---|
| 164 | PT_PAD = 11 | BYTE - padding for even boundary
|
---|
| 165 |
|
---|
| 166 | MSK_MNT = 0xFFF0 | mask for mantissa (in PT_TIM)
|
---|
| 167 | MSK_EXP = 0x000F | mask for exponent (in PT_TIM)
|
---|
| 168 |
|
---|
| 169 | MAX_ACT = 7 | maximum action code value
|
---|
| 170 |
|
---|
[f40a309] | 171 | .page
|
---|
[4f508e6] | 172 |
|
---|
| 173 | | ------------------------------------------------------------------------------
|
---|
| 174 | | pflist definitions -- must match those in instdsp.h
|
---|
| 175 |
|
---|
| 176 | PF_NEXT = 0
|
---|
| 177 | PF_TRIG = 4
|
---|
| 178 | PF_FUNC = 6
|
---|
| 179 | PF_D1 = 8
|
---|
| 180 | PF_D2 = 12
|
---|
| 181 | PF_D4 = 16
|
---|
| 182 | PF_A1 = 20
|
---|
| 183 | PF_A2 = 24
|
---|
| 184 | PF_A3 = 28
|
---|
| 185 | | ------------------------------------------------------------------------------
|
---|
| 186 | | Source definitions -- must match those in 'smdefs.h'
|
---|
| 187 |
|
---|
| 188 | SM_RAND = 1 | random
|
---|
| 189 | SM_PTCH = 5 | pitch
|
---|
| 190 | SM_KPRS = 6 | key pressure
|
---|
| 191 | SM_KVEL = 7 | key velocity
|
---|
| 192 | SM_FREQ = 10 | frequency
|
---|
| 193 |
|
---|
[f40a309] | 194 | .page
|
---|
[4f508e6] | 195 | | ------------------------------------------------------------------------------
|
---|
[8325447] | 196 | | fpuint() -- process FPU interrupts
|
---|
[4f508e6] | 197 |
|
---|
| 198 | | void
|
---|
| 199 | | fpuint();
|
---|
| 200 |
|
---|
| 201 | | Processes FPU interrupts. Must be the target of vector 26,
|
---|
| 202 | | which is Autovector Interrupt level 2.
|
---|
| 203 |
|
---|
| 204 | | ------------------------------------------------------------------------------
|
---|
| 205 |
|
---|
[8325447] | 206 | fpuint: movem.l d0-d5/a0-a3,-(a7) | preserve registers we use
|
---|
[4f508e6] | 207 | move.w FPUINT1,d0 | read FPU interrupt status
|
---|
| 208 | andi.w #0x00FF,d0 | mask out garbage in MS bits
|
---|
[8325447] | 209 | move.w d0,fpuifnc | save for later use
|
---|
| 210 | move.w ndisp,d1 | get display number
|
---|
[4f508e6] | 211 | cmpi.w #11,d1 | see if we display
|
---|
| 212 | bne nodisp | jump if not
|
---|
| 213 |
|
---|
[8325447] | 214 | tst.w scopef | ...
|
---|
[4f508e6] | 215 | beq nodisp | ...
|
---|
| 216 |
|
---|
| 217 | move.w d0,-(a7) | display value
|
---|
[8325447] | 218 | jsr scope | ...
|
---|
[4f508e6] | 219 | tst.w (a7)+ | ...
|
---|
| 220 |
|
---|
[8325447] | 221 | move.w fpuifnc,d0 | get FPU status
|
---|
[4f508e6] | 222 |
|
---|
| 223 | nodisp: move.w d0,d1 | save in d1 (becomes function offset)
|
---|
| 224 |
|
---|
| 225 | lsl.w #5,d1 | develop FPU function offset
|
---|
| 226 | lea FPUFUNC,a3 | setup FPU function base address
|
---|
| 227 |
|
---|
| 228 | lsl.w #3,d0 | develop funcndx[] index
|
---|
[8325447] | 229 | lea funcndx,a0 | setup funcndx[] base address
|
---|
[4f508e6] | 230 |
|
---|
| 231 | tst.l 0(a0,d0.W) | see if function is defined
|
---|
| 232 | bne fnok | jump if so
|
---|
| 233 |
|
---|
| 234 | move.w d1,d0 | get function offset in d0
|
---|
| 235 | andi.w #0x1E00,d0 | mask for voice number
|
---|
| 236 | cmpi.w #0x1800,d0 | see if it's a real voice (0..11)
|
---|
| 237 | bge fpexit | don't send a kill if not a real voice
|
---|
| 238 |
|
---|
| 239 | move.w #FKILL,F_CTL(a3,d1.W) | kill the undefined function
|
---|
| 240 |
|
---|
| 241 | fpexit: clr.w FPUINT2 | reset the FPU interrupt latch
|
---|
| 242 | movem.l (a7)+,d0-d5/a0-a3 | restore the registers
|
---|
| 243 | rte | return to interrupted code
|
---|
| 244 |
|
---|
[f40a309] | 245 | .page
|
---|
[4f508e6] | 246 | | ------------------------------------------------------------------------------
|
---|
| 247 | | set up to process active functions, stop ones that should be inactive
|
---|
| 248 | | ------------------------------------------------------------------------------
|
---|
| 249 | fnok: movea.l 0(a0,d0.W),a1 | get pointer to function header
|
---|
| 250 | movea.l 4(a0,d0.W),a2 | get pointer to point table
|
---|
| 251 | btst #I_ACTIVE,FH_TMD(a1) | see if function is active
|
---|
| 252 | bne doact | go process action if so
|
---|
| 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 fpexit | go restore registers and exit
|
---|
| 266 |
|
---|
[f40a309] | 267 | .page
|
---|
[4f508e6] | 268 | | ------------------------------------------------------------------------------
|
---|
| 269 | | setup for and dispatch to the proper action handler
|
---|
| 270 | | ------------------------------------------------------------------------------
|
---|
| 271 | doact: clr.w d2 | get current point index in d2
|
---|
| 272 | move.b FH_CPT(a1),d2 | ...
|
---|
| 273 | lsl.w #2,d2 | multiply it by the length of a point
|
---|
| 274 | move.w d2,d0 | ... (fast multiply by PT_LEN = 12
|
---|
| 275 | add.w d2,d2 | ... via shift and add)
|
---|
| 276 | add.w d0,d2 | ...
|
---|
| 277 | clr.w d4 | get jump point # into d4
|
---|
| 278 | move.b PT_PAR1(a2,d2.W),d4 | ...
|
---|
| 279 | clr.w d3 | get action code in d3
|
---|
| 280 | move.b PT_ACT(a2,d2.W),d3 | ...
|
---|
| 281 | cmpi.b #MAX_ACT,d3 | check against the limit
|
---|
| 282 | bgt stopfn | stop things if it's a bad action code
|
---|
| 283 |
|
---|
| 284 | lsl.w #2,d3 | develop index to action dispatch table
|
---|
| 285 | lea actab,a0 | get the address of the action handler
|
---|
| 286 | movea.l 0(a0,d3.W),a0 | ...
|
---|
| 287 |
|
---|
| 288 | | ------------------------------------------------------------------------------
|
---|
| 289 | | At this point we're ready to do the action associated with the point,
|
---|
| 290 | | and the registers are set up, and will remain, as follows:
|
---|
| 291 |
|
---|
| 292 | | d1 FPU function index a1 function header base
|
---|
| 293 | | d2 point table index a2 point table base
|
---|
| 294 | | a3 FPU function base
|
---|
| 295 | | d4 jump point number
|
---|
| 296 |
|
---|
| 297 | | d0, d3, d5, and a0 are used as scratch throughout the code.
|
---|
| 298 |
|
---|
| 299 | | ------------------------------------------------------------------------------
|
---|
| 300 |
|
---|
[8325447] | 301 | fputrap: jmp (a0) | dispatch to action handler
|
---|
[4f508e6] | 302 |
|
---|
[f40a309] | 303 | .page
|
---|
[4f508e6] | 304 | | ------------------------------------------------------------------------------
|
---|
| 305 | | act0 -- AC_NULL -- no action
|
---|
| 306 | | ---- --------------------
|
---|
| 307 | act0: move.b FH_PT1(a1),d0 | get first point number
|
---|
| 308 | add.b FH_PIF(a1),d0 | add number of points in function
|
---|
| 309 | subq.b #1,d0 | make it last point number
|
---|
| 310 | cmp.b FH_CPT(a1),d0 | see if we're at the last point
|
---|
| 311 | beq stopfn | stop function if so
|
---|
| 312 |
|
---|
| 313 | addq.b #1,FH_CPT(a1) | update function header for next point
|
---|
| 314 | addi.w #PT_LEN,d2 | advance the point index
|
---|
| 315 |
|
---|
| 316 | | ------------------------------------------------------------------------------
|
---|
| 317 | | outseg -- output a segment
|
---|
| 318 | | ------ ----------------
|
---|
| 319 | outseg: move.w PT_TIM(a2,d2.w),d3 | get packed time
|
---|
| 320 | move.w d3,d0 | extract mantissa
|
---|
| 321 | andi.w #MSK_MNT,d0 | ...
|
---|
[8325447] | 322 | mulu timemlt,d0 | multiply by panel time pot value
|
---|
[4f508e6] | 323 | lsr.l #8,d0 | ... and scale it
|
---|
| 324 | lsr.l #7,d0 | ...
|
---|
| 325 | move.w d0,F_MNT(a3,d1.W) | send mantissa to FPU
|
---|
| 326 | andi.w #MSK_EXP,d3 | extract exponent code
|
---|
| 327 | add.w d3,d3 | look up decoded exponent
|
---|
[8325447] | 328 | lea expbit,a0 | ... in expbit
|
---|
[4f508e6] | 329 | move.w 0(a0,d3.W),F_EXP(a3,d1.W) | send exponent to FPU
|
---|
| 330 | move.w PT_VAL(a2,d2.W),d3 | get the function value
|
---|
| 331 |
|
---|
| 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()
|
---|
[8325447] | 350 | jsr xgetran | call for a random number
|
---|
[4f508e6] | 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 |
|
---|
[f40a309] | 356 | .page
|
---|
[4f508e6] | 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 #0x01FE,d0 | mask out extraneous bits
|
---|
[8325447] | 366 | lea ptoftab,a0 | get entry from ptoftab[]
|
---|
[4f508e6] | 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
|
---|
[8325447] | 387 | lea veltab,a0 | ... into veltab[]
|
---|
[4f508e6] | 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
|
---|
[8325447] | 399 | lea prstab,a0 | ... into prstab[]
|
---|
[4f508e6] | 400 | move.w 0(a0,d0.W),d5 | get the pressure from prstab[trg]
|
---|
| 401 | bra applym | go apply the multiplier
|
---|
| 402 |
|
---|
[f40a309] | 403 | .page
|
---|
[4f508e6] | 404 | | ------------------------------------------------------------------------------
|
---|
| 405 | | all other sources come out of the valents[] array
|
---|
| 406 | | ------------------------------------------------------------------------------
|
---|
[8325447] | 407 | srctyp4: lea vce2grp,a0 | point at vce2grp[]
|
---|
| 408 | move.w fpuifnc,d5 | get voice number in d5
|
---|
[4f508e6] | 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 | ...
|
---|
[8325447] | 419 | lea valents,a0 | get base of valents[]
|
---|
[4f508e6] | 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 |
|
---|
[f40a309] | 443 | .page
|
---|
[4f508e6] | 444 | | ------------------------------------------------------------------------------
|
---|
| 445 | | adjust the value according to the function type
|
---|
| 446 | | ------------------------------------------------------------------------------
|
---|
| 447 | nosrc: 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 |
|
---|
| 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 |
|
---|
[f40a309] | 479 | .page
|
---|
[4f508e6] | 480 | | ------------------------------------------------------------------------------
|
---|
| 481 | | filter
|
---|
| 482 | | ------------------------------------------------------------------------------
|
---|
| 483 | outsegf: cmpi.w #P_FILTER,d0 | see if it's 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 |
|
---|
[f40a309] | 506 | .page
|
---|
[4f508e6] | 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
|
---|
[f40a309] | 541 | beq outseg1
|
---|
[4f508e6] | 542 |
|
---|
| 543 | move.w d3,F_VAL01(a3,d1.W) | send value to FPU
|
---|
[f40a309] | 544 | bra outseg2
|
---|
[4f508e6] | 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 fpexit | done -- exit
|
---|
| 552 |
|
---|
[f40a309] | 553 | .page
|
---|
[4f508e6] | 554 |
|
---|
| 555 | | ------------------------------------------------------------------------------
|
---|
| 556 | | act1 -- AC_SUST -- pause if key is down (sustain)
|
---|
| 557 | | ---- ------------------------------------------
|
---|
[8325447] | 558 | act1: move.w fpuifnc,d0 | get voice as a word index
|
---|
[4f508e6] | 559 | lsr.w #3,d0 | ...
|
---|
| 560 | andi.w #0x001E,d0 | ...
|
---|
[8325447] | 561 | lea vce2trg,a0 | point at voice to trigger table
|
---|
[4f508e6] | 562 | move.w 0(a0,d0.W),d0 | get trigger table entry into d0
|
---|
| 563 | cmpi.w #-1,d0 | see if voice is free
|
---|
| 564 | beq act0 | continue function if so
|
---|
| 565 |
|
---|
| 566 | btst #15,d0 | see if voice is held by a pedal
|
---|
| 567 | bne act1a | sustain if so
|
---|
| 568 |
|
---|
| 569 | btst #14,d0 | see if voice is sustained by a pedal
|
---|
| 570 | bne act1a | sustain if so
|
---|
| 571 |
|
---|
[8325447] | 572 | lea trgtab,a0 | point at trigger table
|
---|
[4f508e6] | 573 | tst.b 0(a0,d0.W) | check trigger status
|
---|
| 574 | beq act0 | continue function if not active
|
---|
| 575 |
|
---|
[8325447] | 576 | act1a: move.l pfqhdr,d3 | see if any pflist entries remain
|
---|
[4f508e6] | 577 | beq act0 | continue if not (shouldn't happen!)
|
---|
| 578 |
|
---|
| 579 | move.b FH_PT1(a1),d0 | get first point number
|
---|
| 580 | add.b FH_PIF(a1),d0 | add base to first point
|
---|
| 581 | subq.b #1,d0 | make d0 last point number
|
---|
| 582 | cmp.b FH_CPT(a1),d0 | check current point number
|
---|
| 583 | beq stopfn | done if this is the last point
|
---|
| 584 |
|
---|
| 585 | addq.b #1,FH_CPT(a1) | update current point number
|
---|
| 586 | addi.w #PT_LEN,d2 | advance the point index
|
---|
| 587 | movea.l d3,a0 | acquire a new pflist entry
|
---|
[8325447] | 588 | move.l (a0),pfqhdr | ...
|
---|
| 589 | move.l pflist,(a0) | chain it to pflist
|
---|
| 590 | move.l a0,pflist | ...
|
---|
[4f508e6] | 591 | move.w FH_TRG(a1),PF_TRIG(a0) | set trigger number in entry
|
---|
[8325447] | 592 | move.w fpuifnc,PF_FUNC(a0) | set v/p word in entry
|
---|
[4f508e6] | 593 | movem.l d1-d2/d4/a1-a3,PF_D1(a0) | set registers in entry
|
---|
| 594 | move.b FH_TMD(a1),d0 | stop the function
|
---|
| 595 | andi.w #MSK_RNVB,d0 | ...
|
---|
| 596 | move.w d0,d3 | ...
|
---|
| 597 | add.w d3,d3 | ...
|
---|
| 598 | andi.w #MSK_ONVB,d3 | ...
|
---|
| 599 | or.w d3,d0 | ...
|
---|
| 600 | move.w d0,F_CTL(a3,d1.W) | ...
|
---|
| 601 | bra fpexit | exit
|
---|
| 602 |
|
---|
[f40a309] | 603 | .page
|
---|
[4f508e6] | 604 |
|
---|
| 605 | | ------------------------------------------------------------------------------
|
---|
| 606 | | act2 -- AC_ENBL -- stop if key is up
|
---|
| 607 | | ---- ----------------------------
|
---|
[8325447] | 608 | act2: move.w fpuifnc,d0 | get voice as a word index
|
---|
[4f508e6] | 609 | lsr.w #3,d0 | ...
|
---|
| 610 | andi.w #0x001E,d0 | ...
|
---|
[8325447] | 611 | lea vce2trg,a0 | check to see if voice is free
|
---|
[4f508e6] | 612 | move.w 0(a0,d0.W),d0 | ...
|
---|
| 613 | cmpi.w #-1,d0 | ...
|
---|
| 614 | beq stopfn | if so, stop the function
|
---|
| 615 |
|
---|
| 616 | btst #15,d0 | see if voice is held
|
---|
| 617 | bne act0 | continue if so
|
---|
| 618 |
|
---|
| 619 | btst #14,d0 | ...
|
---|
| 620 | bne act0 | ...
|
---|
| 621 |
|
---|
[8325447] | 622 | lea trgtab,a0 | check trigger table entry
|
---|
[4f508e6] | 623 | tst.b 0(a0,d0.W) | ...
|
---|
| 624 | bne act0 | if trigger is active, continue
|
---|
| 625 |
|
---|
| 626 | bra stopfn | if not, stop the function
|
---|
| 627 |
|
---|
| 628 | | ------------------------------------------------------------------------------
|
---|
| 629 | | act3 -- AC_JUMP -- unconditional jump
|
---|
| 630 | | ---- -----------------------------
|
---|
| 631 | act3: cmp.b FH_PIF(a1),d4 | check jump point against limit
|
---|
| 632 | bcc stopfn | stop function if jump point invalid
|
---|
| 633 |
|
---|
| 634 | clr.w d2 | get index of first point
|
---|
| 635 | move.b FH_PT1(a1),d2 | ...
|
---|
| 636 | add.b d4,d2 | add jump point
|
---|
| 637 | move.b d2,FH_CPT(a1) | make it the current point
|
---|
| 638 | lsl.w #2,d2 | develop new point index in d2
|
---|
| 639 | move.w d2,d0 | ... (fast multiply by PT_LEN = 12
|
---|
| 640 | add.w d2,d2 | ... via shift and add)
|
---|
| 641 | add.w d0,d2 | ...
|
---|
| 642 | bra outseg | output the segment
|
---|
| 643 |
|
---|
[f40a309] | 644 | .page
|
---|
[4f508e6] | 645 |
|
---|
| 646 | | ------------------------------------------------------------------------------
|
---|
| 647 | | act4 -- AC_LOOP -- jump to point PT_PAR1 PT_PAR2 times
|
---|
| 648 | | ---- ----------------------------------------------
|
---|
| 649 | act4: tst.b PT_PAR3(a2,d2.W) | check counter
|
---|
| 650 | bne act4a | jump if it's running
|
---|
| 651 |
|
---|
| 652 | move.b PT_PAR2(a2,d2.W),d0 | get parameter
|
---|
| 653 | subi.w #90,d0 | put parameter in random range
|
---|
| 654 | bmi act4b | treat as normal if < 90
|
---|
| 655 |
|
---|
| 656 | movem.l d1-d2/a0-a2,-(a7) | get ranged random number
|
---|
| 657 | move.w d0,-(a7) | ...
|
---|
[8325447] | 658 | jsr irand | ...
|
---|
[4f508e6] | 659 | tst.w (a7)+ | ...
|
---|
| 660 | movem.l (a7)+,d1-d2/a0-a2 | ...
|
---|
| 661 | move.b d0,PT_PAR3(a2,d2.w) | set counter
|
---|
| 662 | beq act0 | next segment if cntr set to 0
|
---|
| 663 |
|
---|
| 664 | bra act3 | else jump to the point
|
---|
| 665 |
|
---|
| 666 | act4b: move.b PT_PAR2(a2,d2.W),PT_PAR3(a2,d2.W) | set counter
|
---|
| 667 | beq act0 | next segment if cntr set to 0
|
---|
| 668 |
|
---|
| 669 | bra act3 | else jump to the point
|
---|
| 670 |
|
---|
| 671 | act4a: subq.b #1,PT_PAR3(a2,d2.W) | decrement counter
|
---|
| 672 | beq act0 | next segment if cntr ran out
|
---|
| 673 |
|
---|
| 674 | bra act3 | jump if it's still non-zero
|
---|
| 675 |
|
---|
| 676 | | ------------------------------------------------------------------------------
|
---|
| 677 | | act5 -- AC_KYUP -- jump if key is up
|
---|
| 678 | | ---- ----------------------------
|
---|
[8325447] | 679 | act5: move.w fpuifnc,d0 | get voice as a word index
|
---|
[4f508e6] | 680 | lsr.w #3,d0 | ...
|
---|
| 681 | andi.w #0x001E,d0 | ...
|
---|
[8325447] | 682 | lea vce2trg,a0 | check to see if voice is free
|
---|
[4f508e6] | 683 | move.w 0(a0,d0.W),d0 | ...
|
---|
| 684 | cmpi.w #-1,d0 | ...
|
---|
| 685 | beq act3 | if so (inactive), do the jump
|
---|
| 686 |
|
---|
| 687 | btst #15,d0 | see if voice is held
|
---|
| 688 | bne act0 | continue if so
|
---|
| 689 |
|
---|
| 690 | btst #14,d0 | ...
|
---|
| 691 | bne act0 | ...
|
---|
| 692 |
|
---|
[8325447] | 693 | lea trgtab,a0 | check trigger table entry
|
---|
[4f508e6] | 694 | tst.b 0(a0,d0.W) | see if the trigger is active
|
---|
| 695 | beq act3 | if not, do the jump
|
---|
| 696 |
|
---|
| 697 | bra act0 | if so, do next segment
|
---|
| 698 |
|
---|
[f40a309] | 699 | .page
|
---|
[4f508e6] | 700 |
|
---|
| 701 | | ------------------------------------------------------------------------------
|
---|
| 702 | | act6 -- AC_KYDN -- jump if key is down
|
---|
| 703 | | ---- ------------------------------
|
---|
[8325447] | 704 | act6: move.w fpuifnc,d0 | get voice as a word index
|
---|
[4f508e6] | 705 | lsr.w #3,d0 | ...
|
---|
| 706 | andi.w #0x001E,d0 | ...
|
---|
[8325447] | 707 | lea vce2trg,a0 | check to see if voice is free
|
---|
[4f508e6] | 708 | move.w 0(a0,d0.W),d0 | ...
|
---|
| 709 | cmpi.w #-1,d0 | ...
|
---|
| 710 | beq act0 | if so (inactive), continue
|
---|
| 711 |
|
---|
| 712 | btst #15,d0 | see if voice is held
|
---|
| 713 | bne act3 | do jump if so
|
---|
| 714 |
|
---|
| 715 | btst #14,d0 | ...
|
---|
| 716 | bne act3 | ...
|
---|
| 717 |
|
---|
[8325447] | 718 | lea trgtab,a0 | check trigger table entry
|
---|
[4f508e6] | 719 | tst.b 0(a0,d0.W) | see if the trigger is active
|
---|
| 720 | bne act3 | if so, do the jump
|
---|
| 721 |
|
---|
| 722 | bra act0 | if not, do next segment
|
---|
| 723 |
|
---|
| 724 | | ------------------------------------------------------------------------------
|
---|
| 725 | | Test stub
|
---|
| 726 | | ---------
|
---|
| 727 | act7: bra act0 | AC_HERE: treat act7 as AC_NULL
|
---|
| 728 |
|
---|
[f40a309] | 729 | .page
|
---|
[4f508e6] | 730 | | ------------------------------------------------------------------------------
|
---|
| 731 |
|
---|
[8325447] | 732 | | fpuclr -- clear the FPU
|
---|
| 733 | | ------ -------------
|
---|
[4f508e6] | 734 |
|
---|
| 735 | | void
|
---|
| 736 | | fpuclr()
|
---|
| 737 |
|
---|
| 738 | | Resets the FPU functions to their nominal values.
|
---|
| 739 |
|
---|
| 740 | | ------------------------------------------------------------------------------
|
---|
| 741 |
|
---|
[8325447] | 742 | fpuclr: link a6,#0 | link stack frames
|
---|
[4f508e6] | 743 | move.w sr,-(a7) | save the interrupt level
|
---|
| 744 | ori.w #0x0700,sr | turn off interrupts
|
---|
| 745 |
|
---|
| 746 | lea FPUFUNC,a0 | point at the first function
|
---|
[8325447] | 747 | lea fp_resv,a2 | point at reset value table
|
---|
[4f508e6] | 748 | move.w #11,d1 | set the outer loop count
|
---|
| 749 |
|
---|
[f40a309] | 750 | .page
|
---|
[4f508e6] | 751 | | ------------------------------------------------------------------------------
|
---|
| 752 | | reset the 'spare' function for the voice
|
---|
| 753 | | ------------------------------------------------------------------------------
|
---|
| 754 | clr0: move.w #CLREXP,F_EXP(a0) | set time exponent
|
---|
| 755 | tst.l actab | delay
|
---|
| 756 | tst.l actab | ...
|
---|
| 757 | move.w #CLRMNT,F_MNT(a0) | set time mantissa
|
---|
| 758 | tst.l actab | delay
|
---|
| 759 | tst.l actab | ...
|
---|
| 760 |
|
---|
| 761 | move.w #0,F_SF3(a0) | set scale factor 3
|
---|
| 762 | tst.l actab | delay
|
---|
| 763 | tst.l actab | ...
|
---|
| 764 | move.w #0,F_CV3(a0) | set voltage 3
|
---|
| 765 | tst.l actab | delay
|
---|
| 766 | tst.l actab | ...
|
---|
| 767 |
|
---|
| 768 | move.w #0,F_SF2(a0) | set scale factor 2
|
---|
| 769 | tst.l actab | delay
|
---|
| 770 | tst.l actab | ...
|
---|
| 771 | move.w #0,F_CV2(a0) | set voltage 2
|
---|
| 772 | tst.l actab | delay
|
---|
| 773 | tst.l actab | ...
|
---|
| 774 |
|
---|
| 775 | move.w #0,F_SF1(a0) | set scale factor 1
|
---|
| 776 | tst.l actab | delay
|
---|
| 777 | tst.l actab | ...
|
---|
| 778 | move.w #0,F_CV1(a0) | set voltage 1
|
---|
| 779 | tst.l actab | delay
|
---|
| 780 | tst.l actab | ...
|
---|
| 781 |
|
---|
| 782 | move.w (a2),F_VAL10(a0) | set value from variable table
|
---|
| 783 | tst.l actab | delay
|
---|
| 784 | tst.l actab | ...
|
---|
| 785 | move.w (a2)+,F_VAL01(a0) | ...
|
---|
| 786 | tst.l actab | delay
|
---|
| 787 | tst.l actab | ...
|
---|
| 788 | move.w #FSEND,F_CTL(a0) | set control word
|
---|
| 789 | tst.l actab | delay
|
---|
| 790 | tst.l actab | ...
|
---|
| 791 |
|
---|
[f40a309] | 792 | .page
|
---|
[4f508e6] | 793 | adda.w #0x0020,a0 | point at 2nd function
|
---|
| 794 | lea fprescon,a1 | set reset constant pointer
|
---|
| 795 | move.w #14,d0 | set inner loop count
|
---|
| 796 |
|
---|
| 797 | | ------------------------------------------------------------------------------
|
---|
| 798 | | reset the other functions for the voice
|
---|
| 799 | | ------------------------------------------------------------------------------
|
---|
| 800 | clr1: move.w #CLREXP,F_EXP(a0) | set time exponent
|
---|
| 801 | tst.l actab | delay
|
---|
| 802 | tst.l actab | ...
|
---|
| 803 | move.w #CLRMNT,F_MNT(a0) | set time mantissa
|
---|
| 804 | tst.l actab | delay
|
---|
| 805 | tst.l actab | ...
|
---|
| 806 |
|
---|
| 807 | move.w #0,F_SF3(a0) | set scale factor 3
|
---|
| 808 | tst.l actab | delay
|
---|
| 809 | tst.l actab | ...
|
---|
| 810 | move.w #0,F_CV3(a0) | set voltage 3
|
---|
| 811 | tst.l actab | delay
|
---|
| 812 | tst.l actab | ...
|
---|
| 813 |
|
---|
| 814 | move.w #0,F_SF2(a0) | set scale factor 2
|
---|
| 815 | tst.l actab | delay
|
---|
| 816 | tst.l actab | ...
|
---|
| 817 | move.w #0,F_CV2(a0) | set voltage 2
|
---|
| 818 | tst.l actab | delay
|
---|
| 819 | tst.l actab | ...
|
---|
| 820 |
|
---|
| 821 | move.w #0,F_SF1(a0) | set scale factor 1
|
---|
| 822 | tst.l actab | delay
|
---|
| 823 | tst.l actab | ...
|
---|
| 824 | move.w #0,F_CV1(a0) | set voltage 1
|
---|
| 825 | tst.l actab | delay
|
---|
| 826 | tst.l actab | ...
|
---|
| 827 |
|
---|
| 828 | move.w (a1),F_VAL10(a0) | set value from constant table
|
---|
| 829 | tst.l actab | delay
|
---|
| 830 | tst.l actab | ...
|
---|
| 831 | move.w (a1)+,F_VAL01(a0) | ...
|
---|
| 832 | tst.l actab | delay
|
---|
| 833 | tst.l actab | ...
|
---|
| 834 | move.w #FSEND,F_CTL(a0) | set control word
|
---|
| 835 | tst.l actab | delay
|
---|
| 836 | tst.l actab | ...
|
---|
| 837 |
|
---|
[f40a309] | 838 | .page
|
---|
[4f508e6] | 839 | | ------------------------------------------------------------------------------
|
---|
| 840 | | loop through reset for all of the voices and functions
|
---|
| 841 | | ------------------------------------------------------------------------------
|
---|
| 842 | adda.w #0x0020,a0 | point at next function
|
---|
| 843 | dbra d0,clr1 | loop until all funcs. cleared
|
---|
| 844 |
|
---|
| 845 | dbra d1,clr0 | loop until all voices cleared
|
---|
| 846 | | ------------------------------------------------------------------------------
|
---|
| 847 | | clear the FPU interrupt, and return
|
---|
| 848 | | ------------------------------------------------------------------------------
|
---|
| 849 | move.w #0,FPUINT2 | clear FPU interrupt
|
---|
| 850 | move.w (a7)+,sr | restore interrupts
|
---|
| 851 | unlk a6 | unlink stack frames
|
---|
| 852 | rts | return to caller
|
---|
| 853 |
|
---|
[f40a309] | 854 | .page
|
---|
[4f508e6] | 855 |
|
---|
[8325447] | 856 | | clrvce -- quiet a voice
|
---|
| 857 | | ------ -------------
|
---|
[4f508e6] | 858 |
|
---|
| 859 | | void
|
---|
| 860 | | clrvce(vce)
|
---|
| 861 | | short vce;
|
---|
| 862 |
|
---|
| 863 | | Quiet the voice by resetting the FPU functions it uses.
|
---|
| 864 |
|
---|
[8325447] | 865 | clrvce: link a6,#0 | link stack frames
|
---|
[4f508e6] | 866 | move.w sr,-(a7) | save the interrupt level
|
---|
| 867 | ori.w #0x0700,sr | turn off interrupts
|
---|
| 868 |
|
---|
| 869 | lea FPUFUNC+0x20,a0 | point at the 2nd function
|
---|
| 870 | move.w 8(a6),d0 | get voice number
|
---|
| 871 | ext.l d0 | ...
|
---|
| 872 | lsl.l #8,d0 | shift into position
|
---|
| 873 | add.l d0,d0 | ...
|
---|
| 874 | adda.l d0,a0 | add to function base
|
---|
| 875 | lea fprescon,a1 | set reset constant pointer
|
---|
| 876 | move.w #14,d0 | set inner loop count
|
---|
| 877 |
|
---|
| 878 | vclr1: move.l a0,d1 | see if we reset this function
|
---|
| 879 | and.w #0x01F0,d1 | ...
|
---|
| 880 |
|
---|
| 881 | cmpi.w #0x0100,d1 | dynamics ?
|
---|
| 882 | beq vclr2 | skip it if so
|
---|
| 883 |
|
---|
| 884 | move.w #CLREXP,F_EXP(a0) | set time exponent
|
---|
| 885 | tst.l actab | delay
|
---|
| 886 | tst.l actab | ...
|
---|
| 887 | move.w #CLRMNT,F_MNT(a0) | set time mantissa
|
---|
| 888 | tst.l actab | delay
|
---|
| 889 | tst.l actab | ...
|
---|
| 890 |
|
---|
| 891 | cmpi.w #0x0020,d1 | freq 1 ?
|
---|
| 892 | beq vclr3 | don't reset CV3 (fine tune)
|
---|
| 893 |
|
---|
| 894 | move.w #0,F_SF3(a0) | set scale factor 3
|
---|
| 895 | tst.l actab | delay
|
---|
| 896 | tst.l actab | ...
|
---|
| 897 | move.w #0,F_CV3(a0) | set voltage 3
|
---|
| 898 | tst.l actab | delay
|
---|
| 899 | tst.l actab | ...
|
---|
| 900 |
|
---|
| 901 | vclr3: move.w #0,F_SF1(a0) | set scale factor 1
|
---|
| 902 | tst.l actab | delay
|
---|
| 903 | tst.l actab | ...
|
---|
| 904 | move.w #0,F_CV1(a0) | set voltage 1
|
---|
| 905 | tst.l actab | delay
|
---|
| 906 | tst.l actab | ...
|
---|
| 907 |
|
---|
[f40a309] | 908 | .page
|
---|
[4f508e6] | 909 |
|
---|
| 910 | move.w (a1),F_VAL10(a0) | set value from constant table
|
---|
| 911 | tst.l actab | delay
|
---|
| 912 | tst.l actab | ...
|
---|
| 913 | move.w (a1),F_VAL01(a0) | ...
|
---|
| 914 | tst.l actab | delay
|
---|
| 915 | tst.l actab | ...
|
---|
| 916 | move.w #FSEND,F_CTL(a0) | set control word
|
---|
| 917 | tst.l actab | delay
|
---|
| 918 | tst.l actab | ...
|
---|
| 919 |
|
---|
| 920 | vclr2: adda.w #2,a1 | point at next function
|
---|
| 921 | adda.w #0x0020,a0 |
|
---|
| 922 | dbra d0,vclr1 | loop until all funcs. cleared
|
---|
| 923 |
|
---|
| 924 | move.w (a7)+,sr | restore interrupts
|
---|
| 925 | unlk a6 | unlink stack frames
|
---|
| 926 | rts | return to caller
|
---|
| 927 |
|
---|
[f40a309] | 928 | .page
|
---|
[4f508e6] | 929 | | ------------------------------------------------------------------------------
|
---|
[f40a309] | 930 | .data
|
---|
[4f508e6] | 931 | | ------------------------------------------------------------------------------
|
---|
| 932 |
|
---|
| 933 | | actab -- action code dispatch table
|
---|
| 934 | | ----- --------------------------
|
---|
[4cfe69a] | 935 | actab: .dc.l act0 | 0 - AC_NULL: no action
|
---|
| 936 | .dc.l act1 | 1 - AC_SUST: sustain
|
---|
| 937 | .dc.l act2 | 2 - AC_ENBL: enable
|
---|
| 938 | .dc.l act3 | 3 - AC_JUMP: unconditional jump
|
---|
| 939 | .dc.l act4 | 4 - AC_LOOP: jump n times (loop)
|
---|
| 940 | .dc.l act5 | 5 - AC_KYUP: jump if key up (enable jump)
|
---|
| 941 | .dc.l act6 | 6 - AC_KYDN: jump if key down (sustain jump)
|
---|
| 942 | .dc.l act7 | 7 - AC_HERE: here on key up
|
---|
[4f508e6] | 943 |
|
---|
| 944 | | fprescon -- FPU reset constant table
|
---|
| 945 | | -------- ------------------------
|
---|
[4cfe69a] | 946 | fprescon: .dc.w 0x0000 | frq 1 0.00
|
---|
| 947 | .dc.w 0x8300 | level -10.00
|
---|
| 948 | .dc.w 0x0000 | frq 2 0.00
|
---|
| 949 | .dc.w 0x0000 | locn 0.00
|
---|
| 950 | .dc.w 0x0000 | frq 3 0.00
|
---|
| 951 | .dc.w 0x0000 | reson 0.00
|
---|
| 952 | .dc.w 0x0000 | frq 4 0.00
|
---|
| 953 | .dc.w 0x7D00 | dyn +10.00
|
---|
| 954 | .dc.w 0x0000 | ind 1 0.00
|
---|
| 955 | .dc.w 0x3E80 | filt +5.00
|
---|
| 956 | .dc.w 0x0000 | ind 2 0.00
|
---|
| 957 | .dc.w 0x0000 | ind 3 0.00
|
---|
| 958 | .dc.w 0x0000 | ind 4 0.00
|
---|
| 959 | .dc.w 0x0000 | ind 5 0.00
|
---|
| 960 | .dc.w 0x0000 | ind 6 0.00
|
---|
[4f508e6] | 961 |
|
---|
| 962 | | ------------------------------------------------------------------------------
|
---|
[f40a309] | 963 | .bss
|
---|
[4f508e6] | 964 | | ------------------------------------------------------------------------------
|
---|
| 965 |
|
---|
[8325447] | 966 | fp_resv: .ds.w 12 | fpu spare function reset values
|
---|
| 967 | fpuifnc: .ds.w 1 | interrupting function number from FPU
|
---|
[4f508e6] | 968 |
|
---|
[f40a309] | 969 | .end
|
---|